Chutes miner 官方中文版教程

Chutes miner 官方中文版教程
WeekendChutes miner 官方中文版教程
该教程包含在 chutes.ai 上的所有挖矿相关组件。chutes.ai 是一个无需许可、无服务器、以 AI 为中心的计算平台。
我们试图通过 ansible 和 helm/kubernetes 将大部分过程自动化,因此虽然它看起来有很多内容,但实际上入门应该相当容易。
📋 目录
⛏️ TL;DR
在 chutes 上挖矿的目标是提供尽可能多的计算能力,并针对冷启动时间(运行新应用或已被抢占的应用)进行优化。一切都通过 kubernetes 自动化,并由 gepetto.py 脚本协调,以优化成本效率并最大化你在计算中所占的份额。
奖励基于总计算时间(包括因率先为代码应用提供推理而获得的赏金)。
你可能应该运行各种各样的 GPU,从非常便宜的(a10, a5000, t4, 等)到非常强大的(8x h100 节点)。
永远不要注册多个 UID,因为它只会无谓地减少你的总计算时间,并且你会和自己竞争。只需向一个矿工增加容量即可。
奖励/权重是根据 7 天的总计算量计算的,所以开始挖矿时要有耐心。我们想要高质量、稳定、愿意长期参与的矿工!
🔍 组件概述
🛠️ 配置/管理工具
🤖 Ansible
虽然不是严格必需的,但我们强烈鼓励所有矿工使用我们提供的 ansible 脚本来配置服务器。
有许多细微之处和要求是很难手动设置的。
关于如何使用 ansible 脚本的更多信息请见后续章节。
🔒 Wireguard
Wireguard 是一种快速、安全的 VPN 服务,通过 ansible 配置创建,它允许你的节点在不都在同一个内部网络上时进行通信。
通常情况下,你可能希望 CPU 实例在一个提供商(AWS、Google 等),而 GPU 实例在另一个提供商(Latitude、Massed Compute 等),并且由于库存原因,你可能每个都有好几个提供商。
通过安装 Wireguard,你的 kubernetes 集群可以轻松跨越任意数量的提供商。
*这会通过 ansible 脚本自动安装和配置*
☸️ Kubernetes
chutes 矿工的全部内容都必须在 kubernetes 中运行。虽然不是严格必需的,但我们推荐使用 microk8s(这会通过 ansible 脚本自动处理)。
如果你选择不使用 microk8s,你还必须修改或不使用提供的 ansible 脚本。
*这会通过 ansible 脚本自动安装和配置*
🧩 矿工组件
该系统有许多组件和活动部分,所以在做任何事情之前,请先熟悉每一个!
🐘 Postgres
我们在整个 chutes 中大量使用 SQLAlchemy/postgres。所有服务器、GPU、部署等都在 postgresql 中进行跟踪,它以有状态集(statefulset)的形式部署在你的 kubernetes 集群内,并带有持久卷声明(persistent volume claim)。
*这会在通过 helm charts 部署时自动安装和配置*
🔄 Redis
Redis 主要用于矿工内的发布/订阅(pubsub)功能。事件(新的 chute 添加到验证器、GPU 添加到系统、chute 被移除等)在 redis 中触发 pubsub 消息,进而触发代码中的各种事件处理程序。
*这会在通过 helm charts 部署时自动安装和配置*
✅ GraVal Bootstrap
Chutes 使用一个自定义的 c/CUDA 库来验证显卡:https://github.com/rayonlabs/graval
简而言之,它使用由设备信息播种的矩阵乘法来验证 GPU 的真实性,包括显存容量测试(总显存的 95% 必须可用于矩阵乘法)。
发送到 chutes 网络上实例的所有流量都用只能由所宣称的 GPU 解密的密钥进行加密。
当你向 kubernetes 集群添加一个新节点时,服务器上的每个 GPU 都必须使用 GraVal 包进行验证,因此会部署一个引导服务器来完成此任务(自动完成,无需担心)。
每次 chute 启动/部署时,它也需要运行 GraVal 来计算部署 chute 所需的解密密钥。
*这会自动完成*
🔀 注册表代理
为了让 chute docker 镜像保持一定的私密性(因为并非所有镜像都是公开的),我们在每个矿工上都使用了一个注册表代理,它通过 bittensor 密钥签名来注入身份验证。
每个 docker 镜像在 kubelet 看来都是 [validator hotkey ss58].localregistry.chutes.ai:30500/[image username]/[image name]:[image tag]
这个子域名指向 127.0.0.1,因此它总是通过 NodePort 路由和本地优先 k8s 服务流量策略从每个 GPU 服务器上的注册表服务代理加载。
注册表代理本身是一个 nginx 服务器,它向矿工 API 执行一个 auth subrequest。请参阅 nginx configmap:https://github.com/rayonlabs/chutes-miner/blob/main/charts/templates/registry-cm.yaml
注入签名的矿工 API 代码在这里:https://github.com/rayonlabs/chutes-miner/blob/main/api/registry/router.py
然后 Nginx 将请求向上游代理回相关的验证器(基于子域名中的热密钥),验证器会验证签名并用可用于我们自托管注册表的基本身份验证替换这些头信息:https://github.com/rayonlabs/chutes-api/blob/main/api/registry/router.py
*这会在通过 helm charts 部署时自动安装和配置*
⚡ API
每个矿工都运行一个 API 服务,它执行各种任务,包括:
- 服务器/库存管理
- 与验证器 API 的 websocket 连接
- docker 镜像注册表身份验证
*这会在通过 helm charts 部署时自动安装和配置*
🧙♂️ Gepetto
Gepetto 是负责所有 chute(即应用)管理的关键组件。除其他外,它负责实际配置 chutes,扩展/缩减 chutes,尝试获取赏金等。
这是作为矿工需要优化的主要部分!
🚀 入门指南
1. 使用 Ansible 配置服务器
你要做的第一件事是配置你的服务器/kubernetes。
所有服务器都必须是裸机/虚拟机,这意味着它不能在 Runpod、Vast 等上运行,我们目前不支持共享或动态 IP - IP 必须是唯一的、静态的,并提供 1:1 的端口映射。
重要的内存说明!
每 GPU 的 RAM 必须与 VRAM 一样多(或非常接近),这一点非常重要。这意味着,例如,如果你正在使用一台带有 4x a40 GPU(48GB VRAM)的服务器,服务器必须有 >= 48 * 4 = 192 GB 的 RAM!如果每 GPU 的 RAM 没有达到 VRAM 的量,部署很可能会失败,并且你的服务器将无法得到充分利用。
重要的存储说明!
有些提供商以不便的方式挂载主存储,例如 latitude.sh 在使用 raid 1 时将卷挂载到 /home,hyperstack 挂载在 /ephemeral 下,等等。在运行 ansible 脚本之前,请务必登录到你的服务器并检查存储是如何分配的。如果你想要存储空间用于 huggingface 缓存、镜像等,你需要确保尽可能多的空间分配在 /var/snap 下。
你可以通过一个简单的绑定挂载来实现,例如,如果主存储在 /home 下,运行:
Bash
1 | rsync -azv /var/snap/ /home/snap/ |
重要的网络说明!
在开始之前,你必须要么禁用所有层的防火墙(如果你喜欢冒险的话),要么启用以下内容:
- 允许你的清单中所有节点之间的所有流量(所有端口,所有协议,包括 UDP)
- 允许你的所有 GPU 节点上的 kubernetes 临时端口范围,因为 chute 部署的端口将是随机的,在该范围内,并且需要公共可访问性 - 默认端口范围是 30000-32767
- 允许你正在管理/运行 chutes-miner add-node/etc. 的机器访问你的 API 中的各种 nodePort 值,或者干脆让它公开(特别是 API 节点端口,默认为 32000)
作为其他节点连接的 wireguard 主要节点的 CPU 主节点,需要启用 IP 转发 – 例如,如果你的节点在 GCP,你需要勾选一个框来启用 IP 转发。
你需要一个非 GPU 服务器(最低 8 核,64gb ram),负责运行 postgres, redis, gepetto, 和 API 组件(而不是 chutes),以及所有的 GPU 服务器 😄(当然是开玩笑,你想用多少就用多少)
前往 ansible 文档,了解如何设置裸机实例的步骤。请务必更新 inventory.yml
2. 配置先决条件
与 kubernetes 交互的最简单方法是在主节点内,但你也可以选择在你的本地机器或其他服务器上进行设置。要这样做:
- 安装 kubectl
- 通过
microk8s config从 CPU 主节点复制 kubernetes 配置,并将其放在你的工作站的~/.kube/config - 将集群的 IP 地址替换为主节点的公共 IP 地址
- 由于 IP 将与证书不匹配,因此在从该服务器运行任何 kubectl 命令时,你需要指定
--insecure-skip-tls-verify(在主节点上进行时则不需要)
如果你打算使用主节点,你应该为 kubectl 和 helm 设置别名:
Bash
1 | echo 'alias kubectl="microk8s kubectl"' >> .bashrc |
你需要手动设置一些东西:
- 创建一个 docker hub 登录以避免在拉取公共镜像时被限速(你可能根本不需要这个,但这无妨):
- 前往 https://hub.docker.com/ 并注册,为公共只读访问生成一个新的个人访问令牌,然后创建 secret:
1 | kubectl create secret docker-registry regcred --docker-server=docker.io --docker-username=[用你的用户名替换] --docker-password=[用你的访问令牌替换] --docker-email=[用你的邮箱替换] |
- 创建矿工凭证
- 你需要从你将用于挖矿的热密钥文件中找到 ss58Address 和 secretSeed,例如
cat ~/.bittensor/wallets/default/hotkeys/hotkey
- 你需要从你将用于挖矿的热密钥文件中找到 ss58Address 和 secretSeed,例如
1 | kubectl create secret generic miner-credentials \ |
完整的 secret 创建示例
这里有一个使用一次性密钥的例子。假设你像这样创建了一个热密钥:
Bash
1 | $ btcli wallet new_hotkey --wallet.name offline --wallet.hotkey test --wallet.path ~/.bittensor/wallets |
打印出该热密钥的内容,并可选地通过 jq 进行美化:
Bash
1 | $ cat ~/.bittensor/wallets/offline/hotkeys/test | jq . |
要从这个密钥创建 secret,命令将是:
Bash
1 | kubectl create secret generic miner-credentials \ |
3. 配置你的环境
请务必仔细检查 values 并根据你的特定环境进行更新。
主要要更新的部分:
a. 验证器
与大多数子网不同,chutes 的验证器列表必须显式配置,而不是依赖于元图(metagraph)。
由于在此子网上操作验证器极其复杂且开销巨大,我们希望大多数验证器会选择使用子热密钥功能,而不是运行自己的验证器。
因此,你希望支持的任何验证器都必须在顶层的 validators 部分进行配置:
默认的主网配置是:
YAML
1 | validators: |
b. huggingface 模型缓存
为了实现更快的冷启动,kubernetes 部署使用 hostPath 挂载来缓存 huggingface 模型。默认设置是在消耗超过 500gb 且模型超过 7 天时清除:
YAML
1 | cache: |
你可以在 overrides 块中按节点覆盖设置,例如:
YAML
1 | cache: |
在此示例中,默认将为 850GB,而 node-0 将有 5TB。
如果你有大量存储空间,你可能希望增加此值或更改其他默认设置。
c. minerApi
默认设置应该非常好,但如果你想更改端口,你可能需要调整服务,即 nodePort。
YAML
1 | minerApi: |
d. 其他
你可以随意调整 redis/postgres/等,但可能没有必要。
4. 用你的优化策略更新 Gepetto
Gepetto 是作为矿工最重要的组件。它负责选择要部署、扩展、缩减、删除的 chutes 等。
你需要仔细检查此代码并进行任何你认为会为你带来更多总计算时间的更改。
一旦你对 gepetto.py 文件的状态感到满意,你需要在 kubernetes 中创建一个 configmap 对象来存储你的文件(从克隆的 chutes-miner 目录内部):
Bash
1 | kubectl create configmap gepetto-code --from-file=gepetto.py -n chutes |
任何时候你想对 gepetto 进行进一步更改,你都需要重新创建 configmap:
Bash
1 | kubectl create configmap gepetto-code --from-file=gepetto.py -o yaml --dry-run=client | kubectl apply -n chutes -f - |
在进行更改后,你还必须重新启动 gepetto 部署,但这仅在你完成设置指南的其余部分之后才有效(在你最初设置矿工时无需运行):
1 | kubectl rollout restart deployment/gepetto -n chutes |
5. 在你的 Kubernetes 集群内部署矿工
首先,而且只运行一次,你需要为 postgres 和 redis 生成密码 - 永远不要运行超过一次,否则会出问题!
在 charts 目录下执行此命令:
Bash
1 | helm template . --set createPasswords=true -s templates/one-time-passwords.yaml | kubectl apply -n chutes -f - |
一旦 secret 创建完毕,你就可以随时运行此命令来生成你的部署 charts,同样是在 charts 目录下:
Bash
1 | helm template . -f values.yaml > miner-charts.yaml |
任何时候你更改 values.yaml,你都将需要重新运行 template 命令以获取更新后的 charts!
然后,你将使用以下命令部署 chutes 组件:
Bash
1 | kubectl apply -f miner-charts.yaml -n chutes |
6. 注册
在子网 64 上注册为矿工。
Bash
1 | btcli subnet register --netuid 64 --wallet.name [COLDKEY] --wallet.hotkey [HOTKEY] |
你不应该在此处宣布一个 axon!所有通信都通过客户端初始化的 socket.io 连接完成,因此公共 axon 没有任何用处,只是一个安全风险。
7. 将你的 GPU 节点添加到清单中
启用矿工中的 GPU 节点的最后一步是使用 chutes-miner CLI 中的 add-node 命令。这会调用矿工 API,触发启动 graval 验证服务等。对于每个 GPU 节点,此命令必须且只运行一次,以便它们可被你的矿工使用。
确保你安装了 chutes-miner-cli 包(你可以在 CPU 节点、你的笔记本电脑、任何地方执行此操作):
Bash
1 | pip install chutes-miner-cli |
为你的清单中的每个 GPU 节点运行此命令:
Bash
1 | chutes-miner add-node \ |
- 这里的
--name对应于你的 ansible inventory.yaml 文件中的短名称,它不是完整的 FQDN。 --validator是该服务器将被分配到的验证器的热密钥 ss58 地址--hourly-cost是你为该服务器上的每个 GPU 每小时支付的费用;gepetto 的优化策略之一是在选择服务器部署 chutes 时将成本最小化--gpu-short-ref是该服务器上 GPU 类型的简短标识符字符串,例如a6000,l40s,h100_sxm等。支持的 GPU 列表可以在这里找到--hotkey是你注册时使用的热密钥文件的路径,用于签署请求,以便通过矿工 API 管理你系统上的清单--miner-api是你的矿工 API 服务的基准 URL,它将是http://[非 GPU 节点 IP]:[minerAPI 端口,默认为 32000],即找到你的仅 CPU 节点的公共/外部 IP 地址,以及你为 API 服务配置的任何端口(如果你没有更改默认设置,则为 32000)。
你可以随时通过简单地更新 inventory.yaml 并重新运行 site.yaml 和 join-cluster.yaml 脚本来添加额外的 GPU 节点:ansible readme
➕ 添加服务器
要扩展你的矿工库存,你应该使用 ansible 脚本来引导它们,特别是 site 和 join-cluster 部分。有关 ansible 部分的信息在这里
然后,运行上面的 chutes-miner add-node ... 命令。
节点引导
为确保成功的最高概率,你应该使用 Ubuntu 22.04 来配置你的服务器,如果可能的话,最好不要安装任何 nvidia 驱动程序。
开始前的网络说明!!!
在做任何事情之前,你应该检查你的服务器提供商使用的 IP 地址,并确保你没有将 Wireguard 使用的网络与它们重叠。默认情况下,chutes 为此目的使用 192.168.0.0/20,但这可能与某些提供商冲突,例如通过 Shadeform 的 Nebius 有时会使用 192.168.x.x 的网络空间。如果网络重叠,你的路由表将会有冲突的条目,机器基本上可能会因此而“砖化”。
为 Wireguard 使用不同的网络是相当简单的,或者甚至只是在 192.168.x.x 空间中使用不同的不重叠范围,但前提是你从一开始就使用该网络。在你已经用不同的 Wireguard 网络配置设置好矿工之后再迁移是需要一些努力的。
要使用不同的范围,只需更新这四个文件:
join-cluster.yml包含一个用于搜索正确网络加入命令的正则表达式,如果不是使用 192.168* 则需要更新templates/wg0-worker.conf.j2指定了 192.168.0.0/20 作为 wireguard 网络,你可以更改它或限制它,例如192.168.254.0/24或使用一个完全不同的私有网络,如10.99.0.0/23或其他任何,只需注意你的 CIDRtemplates/wg0-primary.conf.j2与 worker 配置相同,CIDR 必须匹配inventory.yml显然你的主机需要更新wireguard_ip值以匹配
我不建议如果你已经在运行的情况下更改 wireguard 网络,除非你绝对需要。如果你确实需要,最好的办法是彻底清除 microk8s 并重新开始运行 wireguard, site, 和 extras 脚本,这意味着你必须:
chutes-miner scorch-remote ...以从验证器中清除所有实例/GPU- 在每个节点(GPU 和 CPU)上运行
sudo snap remove microk8s - 重新安装所有东西。
- 重新添加所有节点。
你可以使用三个主要的私有网络:10.0.0.0/8、172.16.0.0/12、192.168.0.0/16,有时你甚至可以使用运营商 NAT 范围 100.64.0.0/10。这些都是巨大的 IP 范围,你几乎肯定可以使用一个 /24,除非你计划向你的矿工添加超过 256 个节点。/23 翻倍,/22 再翻倍,等等。只需选择一个不太可能被使用的范围,或者在选择之前检查你选择的服务器提供商上的服务器。
external_ip
chutes API/验证器直接向每个 GPU 节点发送流量,并且根本不通过主 CPU 节点路由。为了使系统正常工作,这意味着每个 GPU 节点必须有一个可公开路由的 IP 地址,并且不位于共享 IP 后面(因为它使用 kubernetes nodePort 服务)。这个 IP 是公共 IPv4,并且不能是私有 IP 范围内的,如 192.168.0.0/16, 10.0.0.0/8, 等。
这个公共 IP 必须是专用的,并且对于出站和入站流量都是相同的。这意味着,为了让一个节点通过验证,当验证器连接到它时,你作为矿工宣称的 IP 地址必须与当你的节点获取远程令牌时验证器看到的 IP 地址匹配,也就是说,如果基础节点通过其他 IP 路由回互联网,你不能使用带有 NAT/端口映射的共享 IP。
1. 安装 ansible(在你的本地系统上,而不是矿工节点)
Mac
如果你还没有,设置 homebrew:
Bash
1 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" |
然后安装 ansible:
Bash
1 | brew install ansible |
Ubuntu/Ubuntu (WSL)/基于 aptitude 的系统
Bash
1 | sudo apt -y update && sudo apt -y install ansible python3-pip |
CentOS/RHEL/Fedora
如果你还没有安装 epel 仓库(并且它不是 fedora):
Bash
1 | sudo dnf install epel-release -y |
安装 ansible:
Bash
1 | sudo dnf install ansible -y |
2. 安装 ansible collections
Bash
1 | ansible-galaxy collection install community.general |
可选:Ansible 性能调优
Bash
1 | wget https://files.pythonhosted.org/packages/source/m/mitogen/mitogen-0.3.22.tar.gz |
然后在你的 ansible.cfg 中
1 | [defaults] |
3. 更新清单配置
使用你最喜欢的文本编辑器(当然是 vim),编辑 inventory.yml 以满足你的需求。
例如:
YAML
1 | all: |
4. 通过 wireguard 连接网络
Bash
1 | ansible-playbook -i inventory.yml wireguard.yml |
5. 引导!
Bash
1 | ansible-playbook -i inventory.yml site.yml |
6. 将 kubernetes 节点连接在一起
如果你有多个主机,请确保它们都属于同一个集群:
Bash
1 | ansible-playbook -i inventory.yml join-cluster.yml |
7. 安装第三方 helm charts
此步骤将在你的服务器上安装 nvidia GPU operator 和 prometheus。
你只需要运行此命令一次(尽管再次运行也不会造成任何问题)。
Bash
1 | ansible-playbook -i inventory.yml extras.yml |
在事后添加新节点
首先,用新的主机配置更新你的 inventory.yml。
然后,将节点添加到你的 wireguard 网络:
Bash
1 | ansible-playbook -i inventory.yml wireguard.yml |
然后,使用 --limit {hostname} 运行 site 脚本,例如:
Bash
1 | ansible-playbook -i inventory.yml site.yml --limit chutes-h200-0 |
然后,将新节点加入集群(此处不要使用 --limit!):
Bash
1 | ansible-playbook -i inventory.yml join-cluster.yml |







