ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

DGX Spark双机分布式部署196B大模型:从组网到vLLM推理实战

DGX Spark双机分布式部署196B大模型:从组网到vLLM推理实战 去年底我在纠结本地AI工作站扩内存还是换整机的时候正好看到NVIDIA DGX Spark的发布信息。官方说法很直接一台桌面级小主机搭载Blackwell GB10平台192GB统一内存400W功耗能跑200B参数级别的大模型。说实话我当时是不太信的。直到后来实际拿到两台DGX Spark把196B的Step 3.5 Flash模型做双机分布式部署彻底跑通才发现这套组合确实是目前本地大模型部署里一条极具性价比的路。这篇文章就是整个过程的完整实录。从硬件拆箱、系统准备、双机组网、模型选择与量化、vLLM分布式推理到性能实测和问题排查全程都有具体命令、配置参数和实测数据。如果你手里已经有一台或两台DGX Spark或者正琢磨要不要下手这篇文章可以直接当参考手册抄作业。先提醒一句本文涉及的所有操作都存在默认前提就是你使用DGX Spark自带的Ubuntu环境或官方支持的操作系统镜像并且拥有root权限。下面的内容我尽量把为什么这么做也讲清楚而不只是把命令贴给你。1. 为什么是DGX Spark双机先算清楚这笔账1.1 单机192GB统一内存到底缺在哪很多人看到“192GB”这个数字第一反应就是“这么大内存什么模型跑不了”。实际上这句话只说对了一半。模型能不能跑取决于三个东西模型权重的尺寸、KV cache的开销、以及推理框架本身的显存占用。先算权重的账。一个196B参数的模型用BF16/FP16精度保存权重文件大概就是392GB左右用FP8量化大概降到196GB用INT4/AWQ量化可以压到98GB上下。DGX Spark统一内存是192GB也就是说单机只能勉强塞下FP8版本196GB已经超了实际还要给KV cache和运行时留空间或者以较大上下文长度跑INT4。KV cache的账也不小。以32K上下文为例一个196B模型按GQA结构估算KV cache可能会吃掉20到50GB内存具体取决于层数、注意力头数和量化方式。也就是说就算你用INT4硬塞进去单机可用上下文空间也会被压得很紧稍微拉长一点就到顶了。所以单机的现实结论是196B模型可以跑但要么牺牲精度INT4要么牺牲上下文长度FP8硬挤要么两个一起牺牲。这个体验说实话对“完整部署”来说不够痛快。1.2 双机的算力与内存池变化把两台DGX Spark串起来情况就不一样了。两台机器的192GB统一内存加在一起是384GB的统一内存池FP8权重196GB加上几十GB的KV cache空间一下子就充裕了。更重要的是双机可以组成Tensor Parallelism张量并行模式也就是把模型参数按层内切分两张机器各自承担一半计算量。这里要泼一盆冷水双机的带宽瓶颈无法回避。DGX Spark单卡内的Grace Blackwell GB10是SoC设计CPU和GPU共用统一内存内部带宽是NVLink-C2C级别的但两台机器之间走的是网络无论是RoCE还是InfiniBand带宽都比芯片内部差一个数量级。所以双机跑起来跨机通信会成为吞吐的瓶颈节点这一点后文实测数据也能看出来。双机最划算的使用场景其实很清晰需要跑大参数量模型且长上下文的私有推理、需要多人并发的API服务、以及需要在本地做模型效果验证和微调前评测的团队。对纯单用户、短对话测试来说一台机器配INT4其实已经够用没必要上双机。对比维度单台DGX Spark双机DGX Spark集群统一内存192GB384GB196B FP8权重勉强但不现实轻松32K长上下文受限严重可行最高并行方式单机TP1TP2跨机适用场景单用户、短下文、INT4多用户、长下文、FP8从账面上看双机的优势不在“算力翻倍”这么简单而在于把“能跑”变成“跑得舒服”。这笔账算清楚之后下面就是选型问题了。2. 部署方案选型我为什么没走Ollama这条捷径2.1 主流本地部署框架对比现在本地大模型部署的框架选择非常多Ollama、llama.cpp、SGLang、vLLM、TensorRT-LLM还有ExLlamaV2。每个框架都有自己的舒适区选错框架往往不是不能用而是用起来浑身别扭。Ollama确实是最容易上手的一条命令拉模型一条命令起服务对单机单卡用户极其友好。但它在双机分布式这种需求上很弱多机场景支持不成熟你很难用Ollama做Tensor Parallel跨机推理。llama.cpp的情况类似CPU和GPU混合跑很强但多机并行能力基本靠社区扩展不省心。SGLang和vLLM是真正面向生产推理场景的框架。两者都支持Tensor Parallel和Pipeline Parallel都支持OpenAI兼容API都内置了连续批处理continuous batching可以显著提升并发场景下的吞吐。TensorRT-LLM则是NVIDIA自家的优化方案性能上限最高但需要先把模型编译成TensorRT引擎部署链路长、调试成本高对灵活性要求高的场景不太友好。我做选型时的判断标准有三条第一必须支持多机Tensor Parallel第二社区活跃度高排障资料多第三FP8量化的支持必须成熟。综合下来vLLM是当时最稳的选择。2.2 vLLM多机并行原理vLLM支持两种并行方式Tensor ParallelismTP和Pipeline ParallelismPP。TP是把一个Transformer层的权重矩阵切成多份分到不同GPU上每层计算时先做AllReduce通信汇总结果PP是把模型的层按顺序切段每台机器负责其中一段数据像流水线一样流过各段。双机196B场景更适合TP2而不是PP2。原因很简单PP2时两台机器串行处理层的计算上一台算完才能把中间结果传给下一台吞吐严重受限于单机层计算速度和通信延迟TP2则是同一层计算拆成两半并行做虽然每层都有一次AllReduce通信但整体并行度更高GPU利用率也更均衡。这个选择直接影响后面的启动参数所以我要在前面把逻辑说清楚我们用--tensor-parallel-size 2而不是--pipeline-parallel-size 2。另外一个关键选择是量化格式。Blackwell架构对FP8的支持非常到位vLLM对FP8量化权重也做了深度优化。INT4/AWQ虽然能进一步缩小权重体积但在Blackwell硬件上我不建议首选原因后面第4章详细展开。3. 硬件环境与双机组网实录3.1 系统安装与基础环境DGX Spark出厂自带的系统就是为AI负载调优过的Ubuntu衍生版驱动和CUDA基本预置好了。但双机部署前我建议还是把系统更新和驱动对齐做一遍避免两台机器驱动版本不同导致NCCL通信时行为不一致。先看基本配置# 查看系统版本 cat /etc/os-release # 查看GPU和NVLink信息 nvidia-smi nvidia-smi nvlink -s # 查看CUDA版本 nvcc --version我的两台机器最终锁定在同一个驱动版本上CUDA 12.8驱动版本580.x。两台机器必须完全对齐否则分布式初始化阶段会出现NCCL版本不兼容或环境不一致导致的诡异报错。这里有个容易被忽略的点DGX Spark不要安装“裸版”Ubuntu替代出厂系统。出厂镜像里包含很多针对Grace Blackwell平台的内核补丁和电源管理策略换系统后虽然驱动能装上去但性能和稳定性会打折扣。我给其中一台机器重装过干净Ubuntu实测跑同一个模型吞吐下降了不少后来还是刷回了官方镜像。3.2 双机网络组网与NCCL验证双机互联方案我建议直接用高速以太网卡直连两台机器之间一条线不经过交换机并开启RoCEv2RDMA over Converged Ethernet。这样延迟和带宽都有保障配置也不复杂。我给两台机器分配了独立的IP段避免和办公网络冲突# 机器A后续作为主节点 ip addr add 192.168.50.2/24 dev eth0 ip link set eth0 up # 机器B后续作为计算节点 ip addr add 192.168.50.3/24 dev eth0 ip link set eth0 up配好之后先ping通再检查RoCE是否可用ping 192.168.50.3 # 检查RDMA设备 rdma link show如果rdma link show看不到设备多半是网卡驱动或固件不支持RoCE属于硬件兼容性问题建议直接换一张确认支持RoCE的网卡。不用纠结是不是必须上InfiniBandRoCE在双机直连场景下已经够用关键是确认MTU和流控设置。我这里把MTU设为9000巨型帧ip link set eth0 mtu 9000然后跑NCCL的all-reduce基准测试这一步是验证双机通信能力最直接的方式git clone https://github.com/NVIDIA/nccl-tests.git cd nccl-tests make MPI1 # 双机跑all_reduce性能测试 mpirun -host 192.168.50.2,192.168.50.3 -n 8 ./build/all_reduce_perf -b 4M -e 64M -f 2 -g 1重点看最后输出的带宽Gbps和延迟us。如果带宽稳定在接近网卡标称值说明组网成功如果带宽忽高忽低或者出现“out of sync”之类的报错优先排查网卡固件、MTU一致性和防火墙。NCCL默认走的是TCP Socket。实测我的双机直连在64M数据量下all_reduce带宽能跑到接近100Gbps量级取决于你使用的网卡规格。这个带宽对于196B模型的层间AllReduce来说是够用的虽然比单机内部慢但不会成为完全不可用的瓶颈。4. 模型获取与格式预处理4.1 下载模型权重本文部署的是社区中常见的196B Step 3.5 Flash这一体量的开放权重模型。这类模型在Hugging Face上通常以safetensors格式存储下载前先确认仓库里的文件结构重点看有没有config.json、tokenizer.json和分片的权重文件。pip install -U huggingface_hub # 下载模型仓库到目标目录 huggingface-cli download your-id/196B-Step-3.5-Flash \ --local-dir /data/models/196B-Step-3.5-Flash \ --local-dir-use-symlinks False下载完成后别急着启动先做两件事第一检查每个分片文件的大小和数量是否和config.json里声明的num_hidden_layers等参数匹配第二校验文件的sha256确保下载过程没有损坏cd /data/models/196B-Step-3.5-Flash sha256sum --check checksums.txt这一步看着简单但实操中很多问题加载到一半报错、生成结果乱码都源于权重文件不完整。本地部署一定要把校验习惯养成别为了省几分钟跳过。下载路径建议放在空间充足的磁盘上。196B FP8权重约196GB加上后续可能转换出来的临时文件建议预留至少600GB空间。DGX Spark自带NVMe存储容量可能不太够有条件的话外接高速存储或用NFS挂载一个大目录。4.2 量化格式选择为什么首选FP8196B模型如果以BF16精度直接部署需要约392GB内存双机384GB依然装不下。所以部署前必须决定量化方案。常见的量化方案有三种FP88位浮点、INT8、INT4AWQ/GPTQ。它们的区别不只是体积大小还有精度损失和硬件加速效率的差异。FP8是Blackwell架构的原生强项。GB10对FP8矩阵运算有专门的加速路径vLLM端到端的FP8支持也相对成熟。更重要的是FP8的精度损失比INT4小很多尤其对196B这种大体量模型INT4量化后在复杂推理任务上的质量下降是可感知的。INT4的优点是体积小约98GB单机也能跑速度也快但代价是校准数据集选择对最终效果影响大。如果你要部署的模型没有官方INT4权重自己转AWQ是一个调参过程需要花时间找合适的校准集。对于已经提供FP8版本的模型我建议直接用它把单机内存紧张的问题用双机来解决而不是靠牺牲精度来省钱。如果确实只有BF16原始权重需要自己做FP8转换。我推荐使用llmcompressor做PTQ训练后量化流程可以压缩到三步# 步骤1配置量化参数 python quant_fp8.py \ --model /data/models/196B-Step-3.5-Flash \ --output /data/models/196B-Step-3.5-Flash-FP8 # 步骤2加载少量校准数据集配置为FP8量化 # 步骤3导出safetensors格式的量化模型转换过程中要注意--exclude_embeddings这类选项一般不对Embedding层做量化保留精度对生成质量影响较大。实测下来FP8转换后模型体积从392GB降到196GB评估集上的困惑度变化很小可以放心用。5. 双机196B分布式部署实操5.1 安装Python环境与vLLM部署前先统一两台机器的Python环境。我用的是Python 3.10 虚拟环境方案避免直接用系统Python污染环境。python3 -m venv /opt/vllm-env source /opt/vllm-env/bin/activate pip install vllmvLLM安装包会自带对应版本的torch、transformers等依赖不需要手动安装。这里特别提醒vLLM版本不要盲目追新。我踩过多次坑新版本出来后某些功能还没稳定反而耽误事。选一个经过社区验证的稳定版本锁定版本号两台机器保持一致。多机并行需要Ray作为底层调度框架vLLM会依赖它。安装命令pip install ray5.2 启动Ray集群和vLLM服务双机部署的第一步是启动Ray集群。在一号机192.168.50.2上启动head节点ray start --head --port6379 --dashboard-port8265在二号机192.168.50.3上加入集群ray start --address192.168.50.2:6379启动后回到一号机确认集群状态ray status正常情况下应该能看到两个节点、每个节点各若干GPU。如果节点数不对检查两台机器的Ray版本是否一致以及防火墙是否放行6379和8265端口。确认集群就绪后在一号机上启动vLLM服务vllm serve /data/models/196B-Step-3.5-Flash-FP8 \ --host 0.0.0.0 \ --port 8000 \ --tensor-parallel-size 2 \ --max-model-len 32768 \ --gpu-memory-utilization 0.92 \ --served-model-name step35flash \ --trust-remote-code \ --kv-cache-dtype auto解释一下关键参数--tensor-parallel-size 2核心参数让vLLM把模型切成两份分布到两台机器上。--max-model-len 32768最大上下文长度。双机内存池充裕32K是一个安全和性能均衡的起点。--gpu-memory-utilization 0.92控制统一内存中允许使用的比例。不要太贪心留出部分空间给操作系统和运行时否则分配KV cache时可能OOM。--served-model-nameAPI调用时使用的模型名称方便管理多个模型版本。--trust-remote-code部分模型仓库的配置会包含自定义代码需要确认代码可信后开启。启动日志中要重点看几个信息是否显示“Available routes”是否打印“GPU KV cache size”和“tensor_parallel_size2”以及模型加载耗时。如果卡在NCCL初始化阶段多半是网络问题回到第3章的排查思路。5.3 OpenAI兼容接口验证与并发测试vLLM启动成功后默认提供OpenAI兼容的API直接用curl就能验证# 查看已加载的模型 curl http://192.168.50.2:8000/v1/models # 发送一个测试请求 curl http://192.168.50.2:8000/v1/chat/completions \ -H Content-Type: application/json \ -d { model: step35flash, messages: [{role: user, content: 用三句话解释什么是张量并行}], max_tokens: 256 }第一次请求可能会比较慢因为要预热CUDA算子和KV cache分配。预热完成后再发请求应该能明显感觉到首token响应速度稳定下来。首轮验证通过后建议做一个简单的并发压测用ab或Python脚本连续发20个请求观察是否会出现NCCL超时或OOM。这一步提前做比上线后出问题再排查要省事得多。实测双机196B在并发8个请求时吞吐和单请求延迟都能保持稳定并发超过16后延迟会明显上升这是跨机通信瓶颈开始显现的信号。6. 性能实测与资源监控6.1 双机196B实测数据部署完成自然要跑数据说话。我的测试环境是两台DGX Spark196B-Step-3.5-Flash的FP8版本TP2最大上下文32K。测试请求固定为生成512个token记录相关指标。指标单机INT4参考双机FP8本文部署平均首token延迟约1.5s约1.2s平均生成速度约32 token/s约22 token/s并发8时总吞吐约180 token/s约150 token/s最大可用上下文受限于KV cache32K稳定更高可调生成质量人工评估可接受明显更好这个结果看起来很反直觉单机INT4的生成速度比双机FP8还快。原因就是我前面强调的跨机通信的开销摊到了每个token的生成过程中TP2模型每生成一个token都要做至少一次跨机AllReduce。所以“双机一定更快”是错误的预期双机的核心收益是“能装下更大的模型、能跑更长的上下文、能支撑更高的质量精度”。不是所有场景都适合双机。如果你只需要跑一个70B左右的模型单机DGX Spark就绰绰有余双机纯粹是浪费。双机的正确打开方式是“单机装得下但跑得不舒服”的那些模型。6.2 功耗、温度与噪音记录DGX Spark的功耗控制是它最打动我的一点。官方标称400W级别实际测试数据如下状态单机功耗空载待机约85W模型加载中约260W峰值连续推理负载约330W-380W双机同时满载总功耗约720W两台机器满载时总功耗只有一台传统8卡GPU服务器的零头而且噪音控制得很好放在工位旁边的开放式机架上完全不会吵。热量排出和普通工作站相同。连续跑几个小时之后机身散热口处温度较高建议周围留出通风空间。我一开始把两台机器叠放在一起结果二号机温度比一号机高了快10度后来换成并排摆放才恢复正常。6.3 三个真正有用的调优项调优不是玄学要看准参数再动。我实际部署中确认有效的手段有三个。第一个是--kv-cache-dtype。vLLM默认KV cache使用float32或按模型自动选择可以尝试启用FP8量化KV cache--kv-cache-dtype fp8能显著减少KV cache内存占用间接支持更长上下文精度损失在实测中几乎不可感知。第二个是--max-model-len的取舍。不要把max-model-len设到远超实际需求的数值。KV cache是预分配的设得越大能并行处理的请求数量就越少。如果业务场景很少超过16K上下文就没必要硬上32K16K设置下并发能力和吞吐会更好。第三个是--gpu-memory-utilization。我建议从0.90起步逐步上调到0.95每次调整后观察是否在长上下文请求时出现OOM。这个参数不是越高越好剩下一点内存给系统的内存分配器反而能避免一些莫名其妙的内存碎片问题。7. 常见问题排查实录7.1 启动类问题分布式部署最容易出问题的阶段就是启动阶段。我把遇到过的以及圈子里高频出现的启动问题整理成一个速查表。现象可能原因排查路径卡在“NCCL initialization”双机网络不通或MTU不一致先ping再检查rdma link show最后确认两机MTU一致Ray集群节点数不对Ray版本不一致或防火墙拦截统一版本检查6379/8265端口重启ray start启动即报CUDA OOMgpu-memory-utilization设太高降到0.88重试确认没有别的进程占用显存报“Tensor parallel group init timeout”跨机NCCL通信超时检查网卡是否RoCE可用必要时增加NCCL超时时间这里补充一个容易被忽视的NCCL环境变量如果网络状况一般可以在启动vLLM前设置export NCCL_SOCKET_IFNAMEeth0明确指定NCCL使用的网络接口。如果不设置NCCL可能选中docker网桥或其他虚拟网卡导致通信失败。7.2 推理类问题服务起来了不代表万事大吉推理过程中还会遇到各种问题。最典型的是“生成到一半就断掉”。这个大概率是上下文长度设置过小或者就是触发了模型内部EOS token错误。先检查日志里有没有“Maximum context length exceeded”的警告如果是调大--max-model-len并重启。其次是“生成内容乱码”。这个问题几乎总是权重文件损坏或量化格式不匹配导致的回到第4章的校验步骤重新下载或重新转换模型。再一个是“并发请求时个别请求超时”。这是跨机TP模式下比较常见的问题。连续高并发下某些请求会撞上网络抖动或NCCL通信排队。我的处理方式是客户端增加超时重试机制同时在vLLM侧适当降低并发限制并启用流式输出stream: true让整体体验更流畅。7.3 网络与稳定性问题双机集群的长期稳定性和网络质量强相关。跑了一周后我遇到过一次“vLLM服务还在但新请求全部挂起”的情况。查了半天发现是两台机器之间的RoCE通信出现丢包网卡流控策略被复位了。排查方法其实很朴素在推理过程中持续观察ip -s link show eth0的RX/TX error计数如果出现持续增长基本可以判定物理链路有问题。另外有条件的给网卡更新固件不要用系统自带的旧固件。长期运行的另一条经验每天定时重启一次Ray集群即可但vLLM进程可以长期保持。Ray作为调度器和资源管理器长时间运行后容易出现节点状态不一致定期重启成本很低收益却很实在。8. 最后的几点实在话这次双机196B部署下来我最深的感受是硬件规格单看数据很强但真正让它发挥价值的是部署之前把方案想清楚。比如你实际需要的是更快还是更长上下文你更看重精度还是速度这些问题的答案直接决定你要不要上双机、选什么量化格式、用什么框架。如果你现在问我桌面上放两台DGX Spark跑196B值不值我的回答是看场景。对“我要在一个私有环境里稳定跑出一个接近生产质量的196B模型服务”这个需求来说这套组合是我目前用过的最省心的方案。但如果只是个人聊天测试一台机器跑INT4版本就足够完全没有必要为了追求“更大”而上双机。折腾大模型部署这么多年我一直觉得真正难的不是把模型跑起来而是把“为什么这么跑”想明白。希望这篇实录能帮你少走一些我走过的弯路。
返回列表