社区供稿 | Hugging Face 使用 Dragonfly 加速分发模型和数据集

875次阅读
没有评论

Dragonfly GitHub Repo:

https://github.com/dragonflyoss/Dragonfly2

本文将帮助您将 Dragonfly 与 Hugging Face 一起使用。当在 Hugging Face 下载数据集以及模型的时候,文件相对较大且会有并发下载文件的场景。这样很容易导致 Hugging Face 的 Git LFS 存储带宽被打满,从而引起下载过慢的情况,影响训练以及推理服务的使用。

社区供稿 | Hugging Face 使用 Dragonfly 加速分发模型和数据集

这种方式比较好的解决方案是使用 Dragonfly 的 P2P 技术利用每个节点的闲置带宽缓解 Git LFS 存储的带宽压力,从而达到加速效果。在最理想的情况下 Dragonfly 可以让整个 P2P 集群中只有一个节点回源 Hugging Face 下载数据集或模型,其他节点流量均使用集群内 P2P 内网带宽。

社区供稿 | Hugging Face 使用 Dragonfly 加速分发模型和数据集

Part.1

集成方案

1.1 依赖

所需软件

版本要求

文档

Kubernetes cluster

1.20+

kubernetes.io

Helm

3.8.0+

helm.sh

注意: 如果没有可用的 Kubernetes 集群进行测试,推荐使用 Kind

1.2 安装 Dragonfly

基于 Kubernetes cluster 详细安装文档可以参考 quick-start-kubernetes

  • 使用 Kind 安装 Kubernetes 集群

创建 Kind 多节点集群配置文件 kind-config.yaml,配置如下:

kind: ClusterapiVersion: kind.x-k8s.io/v1alpha4nodes: - role: control-plane - role: worker extraPortMappings: - containerPort: 30950 hostPort: 65001 - role: worker

使用配置文件创建 Kind 集群:

kind create cluster --config kind-config.yaml

切换 Kubectl 的 context 到 Kind 集群:

kubectl config use-context kind-kind

  • Kind 加载 Dragonfly 镜像

下载 Dragonfly latest 镜像:

docker pull dragonflyoss/scheduler:latestdocker pull dragonflyoss/manager:latestdocker pull dragonflyoss/dfdaemon:latest

Kind 集群加载 Dragonfly latest 镜像:

kind load docker-image dragonflyoss/scheduler:latestkind load docker-image dragonflyoss/manager:latestkind load docker-image dragonflyoss/dfdaemon:latest

  • 基于 Helm Charts 创建 Dragonfly P2P 集群

创建 Helm Charts 配置文件 charts-config.yaml 并且设置 dfdaemon.config.proxy.registryMirror.url 为 Hugging Face 的 LFS 服务的地址, 配置如下:

scheduler: replicas: 1 metrics: enable: true config: verbose: true pprofPort: 18066
seedPeer: replicas: 1 metrics: enable: true config: verbose: true pprofPort: 18066
dfdaemon: metrics: enable: true hostNetwork: true config: verbose: true pprofPort: 18066 proxy: defaultFilter: 'Expires&Key-Pair-Id&Policy&Signature' security: insecure: true tcpListen: listen: 0.0.0.0 port: 65001 registryMirror: # When enable, using header "X-Dragonfly-Registry" for remote instead of url. dynamic: true # URL for the registry mirror. url: https://cdn-lfs.huggingface.co # Whether to ignore https certificate errors. insecure: true # Optional certificates if the remote server uses self-signed certificates. certs: [] # Whether to request the remote registry directly. direct: false # Whether to use proxies to decide if dragonfly should be used. useProxies: true proxies: - regx: repos.* useHTTPS: true
manager: replicas: 1 metrics: enable: true config: verbose: true pprofPort: 18066

使用配置文件部署 Dragonfly Helm Charts:

$ helm repo add dragonfly https://dragonflyoss.github.io/helm-charts/$ helm install --wait --create-namespace --namespace dragonfly-system dragonfly dragonfly/dragonfly -f charts-config.yamlNAME: dragonflyLAST DEPLOYED: Wed Oct 19 04:23:22 2022NAMESPACE: dragonfly-systemSTATUS: deployedREVISION: 1TEST SUITE: NoneNOTES:1. Get the scheduler address by running these commands: export SCHEDULER_POD_NAME=$(kubectl get pods --namespace dragonfly-system -l "app=dragonfly,release=dragonfly,component=scheduler" -o jsonpath={.items[0].metadata.name}) export SCHEDULER_CONTAINER_PORT=$(kubectl get pod --namespace dragonfly-system $SCHEDULER_POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") kubectl --namespace dragonfly-system port-forward $SCHEDULER_POD_NAME 8002:$SCHEDULER_CONTAINER_PORT echo "Visit http://127.0.0.1:8002 to use your scheduler"
2. Get the dfdaemon port by running these commands: export DFDAEMON_POD_NAME=$(kubectl get pods --namespace dragonfly-system -l "app=dragonfly,release=dragonfly,component=dfdaemon" -o jsonpath={.items[0].metadata.name}) export DFDAEMON_CONTAINER_PORT=$(kubectl get pod --namespace dragonfly-system $DFDAEMON_POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") You can use $DFDAEMON_CONTAINER_PORT as a proxy port in Node.
3. Configure runtime to use dragonfly: https://d7y.io/docs/getting-started/quick-start/kubernetes/

检查 Dragonfly 是否部署成功:

$ kubectl get po -n dragonfly-systemNAME READY STATUS RESTARTS AGEdragonfly-dfdaemon-rhnr6 1/1 Running 4 (101s ago) 3m27sdragonfly-dfdaemon-s6sv5 1/1 Running 5 (111s ago) 3m27sdragonfly-manager-67f97d7986-8dgn8 1/1 Running 0 3m27sdragonfly-mysql-0 1/1 Running 0 3m27sdragonfly-redis-master-0 1/1 Running 0 3m27sdragonfly-redis-replicas-0 1/1 Running 1 (115s ago) 3m27sdragonfly-redis-replicas-1 1/1 Running 0 95sdragonfly-redis-replicas-2 1/1 Running 0 70sdragonfly-scheduler-0 1/1 Running 0 3m27sdragonfly-seed-peer-0 1/1 Running 2 (95s ago) 3m27s

创建 Peer Service 配置文件 peer-service-config.yaml 配置如下:

apiVersion: v1kind: Servicemetadata: name: peer namespace: dragonfly-systemspec: type: NodePort ports: - name: http-65001 nodePort: 30950 port: 65001 selector: app: dragonfly component: dfdaemon release: dragonfly

使用配置文件部署 Peer Service:

kubectl apply -f peer-service-config.yaml

1.3 通过 Dragonfly 分发 Hub Python Library 的下载文件流量

任何 Hub Python Library 的 API 使用 Requests 库下载文件,都可以通过设置 DragonflyAdapter 将流量使用 Dragonfly 分发。

  • 使用 Dragonfly 下载单个文件

下载单个文件可以使用 hf_hub_download, 并且通过 Dragonfly 分发流量。

创建 hf_hub_download_dragonfly.py 文件,使用 DragonflyAdapter 将下载流量转发至 Dragonfly HTTP Proxy。这样可以通过 P2P 网络分发流量,内容如下:

import requestsfrom requests.adapters import HTTPAdapterfrom urllib.parse import urlparsefrom huggingface_hub import hf_hub_downloadfrom huggingface_hub import configure_http_backend
class DragonflyAdapter(HTTPAdapter): def get_connection(self, url, proxies=None): # Change the schema of the LFS request to download large files from https:// to http://, # so that Dragonfly HTTP proxy can be used. if url.startswith('https://cdn-lfs.huggingface.co'): url = url.replace('https://', 'http://') return super().get_connection(url, proxies)
def add_headers(self, request, **kwargs): super().add_headers(request, **kwargs)
# If there are multiple different LFS repositories, you can override the # default repository address by adding X-Dragonfly-Registry header. if request.url.find('example.com') != -1: request.headers["X-Dragonfly-Registry"] = 'https://example.com'
# Create a factory function that returns a new Session.def backend_factory() -> requests.Session: session = requests.Session() session.mount('http://', DragonflyAdapter()) session.mount('https://', DragonflyAdapter()) session.proxies = {'http': 'http://127.0.0.1:65001'} return session
# Set it as the default session factoryconfigure_http_backend(backend_factory=backend_factory)
hf_hub_download(repo_id="tiiuae/falcon-rw-1b", filename="pytorch_model.bin")

通过 Dragonfly 基于 LFS 协议下载单个文件:

$ python3 hf_hub_download_dragonfly.py(…)YkNX13a46FCg__&Key-Pair-Id=KVTP0A1DKRTAX: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2.62G/2.62G [00:52<00:00, 49.8MB/s]

  • 验证基于 Dragonfly 下载单个文件

执行命令:

# find podskubectl -n dragonfly-system get pod -l component=dfdaemon# find logspod_name=dfdaemon-xxxxxkubectl -n dragonfly-system exec -it ${pod_name} -- grep "peer task done" /var/log/dragonfly/daemon/core.log

日志输出:

peer task done, cost: 28349ms {"peer": "89.116.64.101-77008-a95a6918-a52b-47f5-9b18-cec6ada03daf", "task": "2fe93348699e07ab67823170925f6be579a3fbc803ff3d33bf9278a60b08d901", "component": "PeerTask", "trace": "b34ed802b7afc0f4acd94b2cedf3fa2a"}

  • 使用 Dragonfly 下载仓库快照

下载仓库快照可以使用 snapshot_download, 并且通过 Dragonfly 分发流量。

创建 snapshot_download_dragonfly.py 文件,使用 DragonflyAdapter 将下载流量转发至 Dragonfly HTTP Proxy。只有 Git LFS 协议的大文件流量会通过 P2P 网络分发,内容如下:

import requestsfrom requests.adapters import HTTPAdapterfrom urllib.parse import urlparsefrom huggingface_hub import snapshot_downloadfrom huggingface_hub import configure_http_backend
class DragonflyAdapter(HTTPAdapter): def get_connection(self, url, proxies=None): # Change the schema of the LFS request to download large files from https:// to http://, # so that Dragonfly HTTP proxy can be used. if url.startswith('https://cdn-lfs.huggingface.co'): url = url.replace('https://', 'http://') return super().get_connection(url, proxies)
def add_headers(self, request, **kwargs): super().add_headers(request, **kwargs)
# If there are multiple different LFS repositories, you can override the # default repository address by adding X-Dragonfly-Registry header. if request.url.find('example.com') != -1: request.headers["X-Dragonfly-Registry"] = 'https://example.com'
# Create a factory function that returns a new Session.def backend_factory() -> requests.Session: session = requests.Session() session.mount('http://', DragonflyAdapter()) session.mount('https://', DragonflyAdapter()) session.proxies = {'http': 'http://127.0.0.1:65001'} return session
# Set it as the default session factoryconfigure_http_backend(backend_factory=backend_factory)
snapshot_download(repo_id="tiiuae/falcon-rw-1b")

通过 Dragonfly 基于 LFS 协议下载仓库快照:

$ python3 snapshot_download_dragonfly.py(…)03165eb22f0a867d4e6a64d34fce19/README.md: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 7.60k/7.60k [00:00<00:00, 374kB/s](…)7d4e6a64d34fce19/configuration_falcon.py: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 6.70k/6.70k [00:00<00:00, 762kB/s](…)f0a867d4e6a64d34fce19/modeling_falcon.py: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 56.9k/56.9k [00:00<00:00, 5.35MB/s](…)3165eb22f0a867d4e6a64d34fce19/merges.txt: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 456k/456k [00:00<00:00, 9.07MB/s](…)867d4e6a64d34fce19/tokenizer_config.json: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 234/234 [00:00<00:00, 106kB/s](…)eb22f0a867d4e6a64d34fce19/tokenizer.json: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2.11M/2.11M [00:00<00:00, 27.7MB/s](…)3165eb22f0a867d4e6a64d34fce19/vocab.json: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 798k/798k [00:00<00:00, 19.7MB/s](…)7d4e6a64d34fce19/special_tokens_map.json: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 99.0/99.0 [00:00<00:00, 45.3kB/s](…)67d4e6a64d34fce19/generation_config.json: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 115/115 [00:00<00:00, 5.02kB/s](…)165eb22f0a867d4e6a64d34fce19/config.json: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1.05k/1.05k [00:00<00:00, 75.9kB/s](…)eb22f0a867d4e6a64d34fce19/.gitattributes: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1.48k/1.48k [00:00<00:00, 171kB/s](…)t-oSSW23tawg__&Key-Pair-Id=KVTP0A1DKRTAX: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2.62G/2.62G [00:50<00:00, 52.1MB/s]Fetching 12 files: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 12/12 [00:50<00:00, 4.23s/it]

  • 验证基于 Dragonfly 下载仓库快照

执行命令:

# find podskubectl -n dragonfly-system get pod -l component=dfdaemon# find logspod_name=dfdaemon-xxxxxkubectl -n dragonfly-system exec -it ${pod_name} -- grep "peer task done" /var/log/dragonfly/daemon/core.log

日志输出:

peer task done, cost: 28349ms {"peer": "89.116.64.101-77008-a95a6918-a52b-47f5-9b18-cec6ada03daf", "task": "2fe93348699e07ab67823170925f6be579a3fbc803ff3d33bf9278a60b08d901", "component": "PeerTask", "trace": "b34ed802b7afc0f4acd94b2cedf3fa2a"}

Part.2

性能测试

测试 Hugging Face Python Library 的 hf_hub_download API 与 Dragonfly 集成后的单机模型文件下载的性能。

由于机器本身网络环境、配置等影响,实际下载时间不具有参考价值, 但是不同场景下载时间所提升的比率是有重要意义的。

社区供稿 | Hugging Face 使用 Dragonfly 加速分发模型和数据集

  • Hugging Face Python Library: 使用 hf_hub_download API 直接下载模型文件。

  • Hugging Face Python Library & Dragonfly Cold Boot: 使用 hf_hub_download API 直接下载模型文件,没有命中任何缓存。

  • Hit Dragonfly Remote Peer Cache: 使用 hf_hub_download API 直接下载模型文件,在命中 Dragonfly 的远端 Peer 缓存。

  • Hit Dragonfly Remote Local Cache: 使用 hf_hub_download API 直接下载模型文件,在命中 Dragonfly 的本地 Peer 缓存。

  • Hit Hugging Face Cache: 使用 hf_hub_download API 直接下载模型文件,在命中 Hugging Face 的缓存。

测试结果表明 Hugging Face Python Library 和 Dragonfly 集成,能够有效减少模型文件下载时间。测试是在单机情况下基本在缓存命中情况下, 性能瓶颈在于磁盘。如果在多节点并发下载数据集或者模型的情况下, Dragonfly 效果会更加明显。

Part.3

相关链接

Dragonfly 社区

  • Website:

    https://d7y.io/

  • Github Repo:

    https://github.com/dragonflyoss/Dragonfly2

  • Slack Channel:

    #dragonfly on CNCF Slack

  • Discussion Group:

    dragonfly-discuss@googlegroups.com

  • Twitter:

    @dragonfly_oss

Hugging Face

  • Website:

    https://huggingface.co/

  • Github Repo:

    https://github.com/huggingface/huggingface_hub

  • Document: 

    https://huggingface.co/docs

  • Hub Python Library: 

    https://huggingface.co/docs/huggingface_hub/index

本文由 Hugging Face 中文社区内容共建项目提供,稿件由社区成员投稿,经授权发布于 Hugging Face 公众号。文章内容不代表官方立场,文中介绍的产品和服务等均不构成投资建议。了解更多请关注公众号:

如果你有与开源 AI、Hugging Face 相关的技术和实践分享内容,以及最新的开源 AI 项目发布,希望通过我们分享给更多 AI 从业者和开发者们,请通过下面的链接投稿与我们取得联系:

https://hf.link/tougao

 

Read More 

正文完
可以使用微信扫码关注公众号(ID:xzluomor)
post-qrcode
 0
评论(没有评论)

文心AIGC

2023 年 11 月
 12345
6789101112
13141516171819
20212223242526
27282930  
文心AIGC
文心AIGC
人工智能ChatGPT,AIGC指利用人工智能技术来生成内容,其中包括文字、语音、代码、图像、视频、机器人动作等等。被认为是继PGC、UGC之后的新型内容创作方式。AIGC作为元宇宙的新方向,近几年迭代速度呈现指数级爆发,谷歌、Meta、百度等平台型巨头持续布局
文章搜索
热门文章
潞晨尤洋:日常办公没必要上私有模型,这三类企业才需要 | MEET2026

潞晨尤洋:日常办公没必要上私有模型,这三类企业才需要 | MEET2026

潞晨尤洋:日常办公没必要上私有模型,这三类企业才需要 | MEET2026 Jay 2025-12-22 09...
面向「空天具身智能」,北航团队提出星座规划新基准丨NeurIPS’25

面向「空天具身智能」,北航团队提出星座规划新基准丨NeurIPS’25

面向「空天具身智能」,北航团队提出星座规划新基准丨NeurIPS’25 鹭羽 2025-12-13 22:37...
5天连更5次,可灵AI年末“狂飙式”升级

5天连更5次,可灵AI年末“狂飙式”升级

5天连更5次,可灵AI年末“狂飙式”升级 思邈 2025-12-10 14:28:37 来源:量子位 让更大规...
钉钉又发新版本!把 AI 搬进每一次对话和会议

钉钉又发新版本!把 AI 搬进每一次对话和会议

钉钉又发新版本!把 AI 搬进每一次对话和会议 梦晨 2025-12-11 15:33:51 来源:量子位 A...
商汤Seko2.0重磅发布,合作短剧登顶抖音AI短剧榜No.1

商汤Seko2.0重磅发布,合作短剧登顶抖音AI短剧榜No.1

商汤Seko2.0重磅发布,合作短剧登顶抖音AI短剧榜No.1 十三 2025-12-15 14:13:14 ...
最新评论
ufabet ufabet มีเกมให้เลือกเล่นมากมาย: เกมเดิมพันหลากหลาย ครบทุกค่ายดัง
tornado crypto mixer tornado crypto mixer Discover the power of privacy with TornadoCash! Learn how this decentralized mixer ensures your transactions remain confidential.
ดูบอลสด ดูบอลสด Very well presented. Every quote was awesome and thanks for sharing the content. Keep sharing and keep motivating others.
ดูบอลสด ดูบอลสด Pretty! This has been a really wonderful post. Many thanks for providing these details.
ดูบอลสด ดูบอลสด Pretty! This has been a really wonderful post. Many thanks for providing these details.
ดูบอลสด ดูบอลสด Hi there to all, for the reason that I am genuinely keen of reading this website’s post to be updated on a regular basis. It carries pleasant stuff.
Obrazy Sztuka Nowoczesna Obrazy Sztuka Nowoczesna Thank you for this wonderful contribution to the topic. Your ability to explain complex ideas simply is admirable.
ufabet ufabet Hi there to all, for the reason that I am genuinely keen of reading this website’s post to be updated on a regular basis. It carries pleasant stuff.
ufabet ufabet You’re so awesome! I don’t believe I have read a single thing like that before. So great to find someone with some original thoughts on this topic. Really.. thank you for starting this up. This website is something that is needed on the internet, someone with a little originality!
ufabet ufabet Very well presented. Every quote was awesome and thanks for sharing the content. Keep sharing and keep motivating others.
热评文章
读懂2025中国AI走向!公司×产品×人物×方案,最值得关注的都在这里了

读懂2025中国AI走向!公司×产品×人物×方案,最值得关注的都在这里了

读懂2025中国AI走向!公司×产品×人物×方案,最值得关注的都在这里了 衡宇 2025-12-10 12:3...
5天连更5次,可灵AI年末“狂飙式”升级

5天连更5次,可灵AI年末“狂飙式”升级

5天连更5次,可灵AI年末“狂飙式”升级 思邈 2025-12-10 14:28:37 来源:量子位 让更大规...
戴尔 x OpenCSG,推出⾯向智能初创企业的⼀体化 IT 基础架构解决方案

戴尔 x OpenCSG,推出⾯向智能初创企业的⼀体化 IT 基础架构解决方案

戴尔 x OpenCSG,推出⾯向智能初创企业的⼀体化 IT 基础架构解决方案 十三 2025-12-10 1...
九章云极独揽量子位三项大奖:以“一度算力”重构AI基础设施云格局

九章云极独揽量子位三项大奖:以“一度算力”重构AI基础设施云格局

九章云极独揽量子位三项大奖:以“一度算力”重构AI基础设施云格局 量子位的朋友们 2025-12-10 18:...
乐奇Rokid这一年,一路狂飙不回头

乐奇Rokid这一年,一路狂飙不回头

乐奇Rokid这一年,一路狂飙不回头 梦瑶 2025-12-10 20:41:15 来源:量子位 梦瑶 发自 ...