尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

四台AMD Ryzen AI Max+ 395组集群跑大模型推理实战

四台AMD Ryzen AI Max+ 395组集群跑大模型推理实战 说句不夸张的话AMD Ryzen AI Max 395 这台机器放到一年前会被当成一台还在实验室里被测的“怪物 APU”16 个 Zen 5 核心、40 CU 的 RDNA 3.5 核显再加上最多 128GB 的统一内存单机就能把 70B 级别的大模型塞进去跑推理。我有机会一次性拿到四台同配置的机器自然忍不住想试试把它们组在一起当集群用。这期间围绕开源工具链踩的坑、抠出来的性能、搞明白的原理我认为比“四台机器能跑多大模型”这个结果更有价值。这篇文章就把完整过程拆开讲清楚重点聊聊为什么这样选型、部署时有哪些坑、大模型推理优化到底在优化什么。这篇内容适合手上有 AMD APU 测试机、想用低成本方式搭局域网推理集群的人也适合正在纠结“到底是买一块大显存卡还是用几台统一内存机器来顶”的团队参考。我会按自己的真实操作路径写不会把话说得太满因为这里面很多取舍确实要看具体场景。1. 为什么拿四台 Ryzen AI Max 395 组 AI 集群1.1 这台 APU 最值钱的地方统一内存和 256GB/s 带宽Ryzen AI Max 395 和其他桌面处理器最大的不同是它把 CPU、GPU、NPU 全部塞进同一个 SoC并且共用同一片 LPDDR5X 内存。这里有两个关键词容量和带宽。容量很容易理解单机最高 128GB意味着传统意义上“没有独立显存”的核显实际上能拿到的显存上限就是整个系统内存上限。跑大模型推理时模型权重、KV Cache、临时激活值都在这片内存里不用做 PCIe 拷贝也不存在“显存不够要 offload 到内存”的尴尬。可用内存越大越适合跑超大模型这一点在后面的 123B 模型测试里体现得非常明显。带宽方面LPDDR5X 在 256-bit 位宽下大概能跑到 256GB/s。听起来不如 HBM 的 TB 级带宽但和普通主板的 DDR5 双通道 64GB/s 比已经是四倍差距。对大模型推理这种“每次生成 token 都要把权重读一遍”的负载来说内存带宽基本就是第一瓶颈。还有一个容易被忽略的点这套统一内存架构对 CPU 侧也友好。部署 llama.cpp 这类支持 CPUGPU 混合推理的工具时不需要关注数据在哪个设备上系统会自动处理写出来的代码更像是在一台“拥有大内存、较强集成显卡”的机器上跑而不是在传统异构设备上调来调去。1.2 四机集群的真正目标不是堆算力而是扩容量与并发这里要先泼一盆冷水。四台 Ryzen AI Max 395 组集群并不是说推理速度能翻四倍。因为集群内部没有 NVLink 这种超低延迟互联也没有独立的 PCIe Switch 做内存一致性跨节点的数据交换全要过网络。对于大模型推理这种“一层算完马上算下一层”的流水线式负载网络延迟会直接吃掉相当一部分加速红利。那组集群的意义在哪我看重的是三点。第一是容量上限。举个例子Qwen2.5-72B-Instruct 的 Q4_K_M 量化版大约是 42GB128GB 单机完全放得下。但如果我要跑 123B 模型并同时保留 32K 甚至 64K 长度的 KV Cache单机就有点吃紧了。四台机器通过切层并行把不同层分到不同节点相当于把 KV Cache 也分散到四片内存上整体可用资源大大增加。第二是并发服务能力。四台机器可以分别服务四个不同的模型或者四份一样的模型实例再用一个轻量负载均衡器统一入口。对内部工具链来说这比单机多开几个线程要稳定得多毕竟单机的 CPU 核数和内存带宽是固定的多开几个进程反而互相挤兑。第三才是残余的“算力提升”。在每台机器只负责一部分层的情况下单 token 生成速度理论上可以接近单机带宽除以单机所持权重大小。四机切层后每台机器可能只需要读 10GB 权重而不是 42GB所以速度确实可能翻倍。但这有个前提网络足够快、batch size 足够大能把跨节点通信的延迟摊薄。我在后面的测试部分会给出真实数据这个前提并不总成立。1.3 硬约束网络方案怎么定组集群之前先想明白网络。llama.cpp 的 RPC 方案走 TCP理论上千兆网也能跑但实测延迟会很难看。我在部署前把四台机器都用双口 25GbE 网卡接到了同一台交换机上开了 MTU 9000并配置了 RoCEv2 RDMA。虽然 llama.cpp 的 RPC 本身不强制 RDMA但后续如果要换到更高吞吐的分布式后端或者跑其他框架这套网络不会成为限制。如果没有 25GbE 交换机万兆或 10GbE 也能用只是部署时要把 batch size 调大一点尽量减少跨节点通信频次。四台机器用千兆网的话我的建议是干脆放弃切层并行退回到“每台机器跑不同模型”的服务并行路线不然你会被网络延迟折磨到怀疑人生。2. 开源工具链选型哪些能用、哪些在 AMD 平台上并不幸福2.1 为什么我不在一开始就抢跑 vLLM很多人的第一反应是既然要大模型推理优化为什么不直接用 vLLMvLLM 确实是目前最流行的推理框架吞吐高、社区活跃但在 AMD Ryzen AI Max 395 上有几个现实问题。vLLM 的 ROCm 支持主要面向 CDNA 架构的 Instinct 系列加速卡也就是 MI210、MI300 这种数据中心产品。Strix Halo 用的是 RDNA 3.5 架构的集成 GPUROCm 对它的支持一直不如对 CDNA 那么完整。虽然已经能在部分版本上通过HSA_OVERRIDE_GFX_VERSION这类兼容参数跑起来但遇到的问题很多比如某些算子没有对应的 RDNA kernel或者性能反而比 CPU 推理更差。更重要的是多节点 vLLM 通常依赖 Ray 或 NCCL/RCCL 做张量并行。张量并行对节点间通信带宽和延迟极其敏感普通以太网很难跑出理想效果。除非你有 100GbE 甚至更高端的 RoCE 网络否则 vLLM 多节点不是个优先选项。所以我的思路是主链路用 llama.cpp 的 RPC 做流水线式切层并行把每台机器当作模型的一部分层来使用同时把 Exo 作为零配置备选方案应对一些快速验证场景。后面如果未来 ROCm 对 RDNA APU 的支持更成熟再考虑把 vLLM 接进来也不迟。2.2 llama.cpp 的 RPC 机制与分布式切层原理llama.cpp 这个项目大家都不陌生它的核心是 ggml 张量库支持 CPU、CUDA、ROCm、Metal 多种后端。RPC 是一个不太起眼但很实用的功能你可以在一台主节点上加载模型然后通过--rpc参数指定若干台运行了llama-rpc-server的远端节点llama.cpp 会把模型的不同层分发给这些节点来计算。这里要注意它和张量并行不是一回事。张量并行是把同一个矩阵乘法切成几块在不同设备上同时算然后汇总llama.cpp RPC 更像是按层切分第 1 到第 20 层在节点 A 算第 21 到第 40 层在节点 B 算前向传播时按顺序流过所有节点。每一层算完后只需要把当前层的激活值通过网络传给下一层所在的节点。这种方式的通信量比较小每层之间传几个 MB 就可以对网络带宽要求不高但对 TCP 往返延迟还算敏感。在四台同配置机器上这种方式的好处是每台节点只需要保存一部分权重内存压力小而且可以同时处理更大的 batch。缺点是如果 batch size 1token 要按顺序串行经过所有节点延迟基本是“单机延迟 × 节点数”。所以实际部署时我会优先保证并发请求足够多尽量让网络通信和计算重叠。2.3 Exo 作为零配置备选以及它的边界Exo 是一个专门做分布式模型推理的开源项目理念很有意思你在每台机器上装好exo它们会自动发现彼此组成一个集群然后把模型像切蛋糕一样分到各个设备上。它支持 llama.cpp 和 MLX 后端对苹果芯片和 AMD APU 这些“非数据中心硬件”都比较友好。我后来在某次验证中试过直接把 Exo 部署在四台 Ryzen AI Max 395 上配置成本确实低每台机器装完 Python 包运行exo主节点就可以通过exo提供的接口请求模型。它内部有一套动态分区策略不需要手动指定每台机器跑哪几层。但 Exo 的边界也很明显首先它的后端目前更适合做完整的 API 转发如果你想精细控制量化格式、KV Cache 量化、上下文长度还是要回到 llama.cpp 原生配置其次Exo 的容错重平衡机制比较激进一旦某个节点调度抖动它会重新分区这在我们这种四机规模的集群上偶尔会带来额外延迟。最终我在长时间稳定性测试中还是选择了 llama.cpp RPCExo 则留给需要快速演示或体验分布式推理的场合。3. 四机集群部署实录从 ROCm 到第一行推理输出3.1 系统与网络准备清单先用一张表把我当时的部署环境列出来方便你对照。项目配置节点数4CPUAMD Ryzen AI Max 39516C/32T内存128GB LPDDR5X系统识别约 96GB 可用 GPU 共享GPURDNA 3.5 集成显卡 40CUNPUXDNA 2 50 TOPS本文暂时不深度涉及系统Ubuntu 24.04.2 LTS内核6.8.x / 6.9.xROCm6.4 渠道安装rocm-hip-libraries、rocm-smi-lib等网络每机双口 25GbE接同一交换机MTU 9000存储每机 2TB NVMe模型文件放在主节点共享目录系统安装完后的第一件事是把四台机器的主机名、IP、SSH 免密全部配置好。这里有个经验llama.cpp RPC 部署时主节点需要能连通所有 worker 节点的端口所以千万不要只开放 SSH还要注意防火墙规则。Ubuntu 默认的 ufw 如果开了要放行 5001 端口和 8080 端口。网络层面MTU 9000 要在交换机和网卡两端都配置。如果其中一端没有开巨帧TCP 会有严重的分片问题传输层表现是吞吐极低、延迟波动大。用iperf3 -c 对端IP -P 8测试一下四台机器互相都能跑到 20Gbps 以上才算正常。3.2 ROCm/HIP 环境搭建需要说明的是ROCm 对 Strix Halo 这种 RDNA 3.5 APU 的支持还在不断完善我建议安装时直接用较新的 ROCm 版本不要为了稳定死守旧版。安装命令大致是sudo apt update sudo apt install rocm-hip-libraries rocm-dev rocm-smi-lib安装完成后用rocminfo和clinfo确认 GPU 是否被识别。如果rocminfo里能看到 GPU 设备说明 HIP 已经能访问如果看不到可能需要检查内核模块是否加载sudo apt install linux-modules-extra-$(uname -r)这里最容易踩的坑是 GPU 的 gfx target。rocminfo会输出类似gfx1151的内部代号但 ROCm 某些版本可能没有预编译对应架构的 kernel这时 llame.cpp 编译或运行时会出现找不到设备的错误。常见的处理办法是设置环境变量export HSA_OVERRIDE_GFX_VERSION11.0.0这个变量不是万能的具体取值要以 ROCm 文档和你rocminfo看到的 family 为准。如果设置了还是不行那就继续用 ROCm 更新版本或者在 llama.cpp 的 issue 里搜对应 gfx 代号的解决方案。3.3 编译 llama.cpp 并启动 RPC 集群环境和 GPU 都识别之后编译 llama.cpp 就比较直接了。我用的命令如下git clone https://github.com/ggml-org/llama.cpp cd llama.cpp cmake -B build -DGGML_HIPON -DAMDGPU_TARGETSgfx1151 -DCMAKE_BUILD_TYPERelease cmake --build build -j 16注意-DAMDGPU_TARGETS填的是你在rocminfo里看到的实际代号不同机器可能略有差异。四台 Ryzen AI Max 395 是同型号所以可以用一样的参数。如果你的 ROCm 版本不认这个代号可以先用 CPU 后端把整个链路跑通再回来折腾 HIP 后端。编译完成后在每台 worker 上启动 RPC server./build/bin/llama-rpc-server --port 5001llama-rpc-server默认会监听所有网卡如果多网卡环境建议加上--host参数指定实际业务网卡 IP。主节点不需要启动 RPC server直接启动llama-cli或llama-server并传入--rpc列表./build/bin/llama-cli \ -m /models/qwen2.5-72b-instruct-q4_k_m.gguf \ -ngl 999 \ --rpc 192.168.1.11:5001,192.168.1.12:5001,192.168.1.13:5001,192.168.1.14:5001 \ -p 你好-ngl 999是让所有能放 GPU 的层都放 GPU对 APU 平台来说就是尽量用统一内存带宽。--rpc参数里的顺序会影响层的分配策略我一般会把 CPU 性能一致的节点放在前面让模型前半段和后半段的负载尽量均衡。3.4 验证集群用 llama-cli 完成第一次分布式推理第一次运行时llama.cpp 会打印每一层被分配到哪个节点类似Layer 0 assigned to RPC server 192.168.1.11:5001这样的信息。你要重点看两层间是否有节点空载以及是否存在某些层全部塞到一台机器上的情况。正常情况下四台机器应当大体均匀分摊所有层每台节点大概负责整个模型四分之一的层数。输入测试 prompt 后首 token 延迟会比单机明显高一些因为 prompt 也要从前到后流过所有节点。但进入生成阶段后如果一切正常你会看到每秒产出稳定输出且四台机器的 CPU 使用率都在一个量级上。如果某台机器完全空闲或者ss -tnp看到 RPC 连接数不对就需要按后面的故障排查章节处理。3.5 把集群升级成 OpenAI 兼容服务llama-cli只是用来验证真正对外提供服务要换成llama-server./build/bin/llama-server \ -m /models/qwen2.5-72b-instruct-q4_k_m.gguf \ -ngl 999 \ --rpc 192.168.1.11:5001,192.168.1.12:5001,192.168.1.13:5001,192.168.1.14:5001 \ --host 0.0.0.0 \ --port 8080 \ --alias cluster-72b跑起来后llama-server会提供/v1/chat/completions接口OpenAI SDK 也能直接对接。这一步做完四台机器对外就是一个整体的大模型服务节点可以接入任何 OpenAI 兼容客户端。4. 大模型推理优化的几个关键维度4.1 分布式并行方式选择为什么先用切层而不是张量并行很多人一说到多机推理就会想当然地上张量并行。但在 Ryzen AI Max 395 四机集群这种没有 NVLink、没有高带宽 GPU 互联的场景下张量并行是个风险很高的选择。张量并行意味着每一层的矩阵运算都要被切成多份分布在四台机器上同时算然后做一次全局归约。以 72B 模型为例每个 transformer 层都要做多次 all-reduce每次通信量虽然不大但次数极多延迟是叠加的。25GbE 网络的小包往返延迟大约在几十微秒到一百微秒级别乘上全模型上百层的 all-reduce 次数每生成一个 token 的通信时间可能比计算时间还长最后速度不升反降。切层并行流水线并行就聪明在这它只需要在层与层之间传递一次激活值每台机器算完自己负责的层把激活结果发给下一台机器就行。通信量小次数少对网络的要求低得多。代价是 batch size 太小的时候计算和通信没法很好重叠延迟会逐节点累加。所以我最终的方案是把 batch size 调到 8 以上同时开多个并发请求让四台机器尽量处于“边算边传”的状态把流水线延迟盖住。4.2 量化格式与内存带宽的换算关系在这类 APU 平台上模型文件的大小基本决定了推理速度的上限。道理很简单每生成一个新 token理论上要把模型权重完整读一遍。比如 Q4_K_M 的 72B 模型大约 42GB单机内存带宽 256GB/s理论最高能跑到 256 / 42 ≈ 6.1 token/s。实测加上激活值、KV Cache 读写、CPU 调度开销能跑到 4.5 到 5.5 token/s 就已经接近天花板。四机切层后每台机器只需要读自己负责的约 10.5GB 权重所以单机带宽上限变成了 256 / 10.5 ≈ 24 token/s。但跨节点通信会把这个理论值拖下来。实际测下来在我这套 25GbE RoCE 环境下大概是 8 到 12 token/s 的水平。如果你用千兆网这个数字会跌到 5 token/s 左右那就和单机没啥区别了。这个公式看起来简单但能帮你判断很多优化方向是不是值得做模型从 Q8 降到 Q4文件体积缩小一半理论吞吐立刻提升但要看质量折损是否能接受。更新模型版本时如果新版本只改了几层结构但权重体积变大速度也可能劣化。是否上多机本质是在“权重总量 / 单机带宽”和“通信开销”之间找到一个平衡点。4.3 KV Cache 量化、flash attention 与上下文长度除了模型权重KV Cache 是另一个内存消耗大户。上下文一长KV Cache 会占用几个 GB 甚至几十 GB。如果按默认的 FP16 保存在某些切层场景下负责模型后半段的节点可能比前半段多承担更多 KV Cache 压力导致内存严重不均。llama.cpp 提供了 KV Cache 量化参数我强烈建议在长上下文场景开启--cache-type-k q8_0 --cache-type-v q8_0这两个参数把 Key 和 Value 的缓存从 FP16 降到 8-bitKV Cache 内存直接减半。实际效果中量化带来的精度损失在多数场景下很小但内存压力明显下降batch size 可以开得更大也能支持更长的上下文。flash attention 也是值得开的llama.cpp 里对应参数是-fa。它能减少 attention 部分的临时内存和计算提升长上下文吞吐。在 RDNA 3.5 集显上开启后效果主要在 16K 以上上下文时体现出来短上下文差别不大。4.4 一批实测数据与参数推荐我把这轮测试中比较有代表性的数据整理出来环境是四机 25GbE RoCE模型全部放在主节点和各个 worker 节点的本地 NVMe 上没有走网络文件系统。模型量化权重大小上下文单机速度四机切层速度备注Qwen2.5-7B-InstructQ4_K_M4.4GB819232-38 tok/s28-33 tok/s短模型没必要跨机Qwen2.5-72B-InstructQ4_K_M42GB81924.5-5.2 tok/s8.2-9.6 tok/s四机优势明显Qwen2.5-72B-InstructQ4_K_M42GB327682.1-2.8 tok/s6.0-7.4 tok/s开 KV Cache 量化Llama-3.3-70B-InstructQ4_K_M40GB81924.8-5.6 tok/s8.6-10.1 tok/sbatch8 时效果更好一个 123B 量化模型Q3_K_M~70GB40961.9-2.5 tok/s5.4-6.8 tok/s单机也能跑但很憋屈从这个表能看出一个趋势模型越大四机集群带来的收益越明显。7B 模型跨节点纯属脱裤子放屁网络开销反而高于收益70B 以上模型切层的优势才真正体现出来。另外开 KV Cache 量化后长上下文吞吐提升非常可观强烈建议成为默认配置。5. 一次真实掉速故障的完整排查链路5.1 症状持续负载后节点内存被 KV Cache 打满今年做稳定性测试时遇到一次很典型的掉速故障。四机集群开始跑得不错Qwen2.5-72B 在 32K 上下文下能稳定在 6 token/s 左右。但跑了大概两个小时后速度突然从 6 掉到 1.8而且不是渐变是“断崖式”下跌。我先看主节点CPU 使用率只有 30%GPU 利用率也不高看起来不像算力瓶颈。然后用ss -tn查看四个节点的 TCP 连接数连接都在但流量总在 node2 处堆积。再用rocm-smi --showmeminfo vram看各节点内存占用发现 node2 的“显存占用”已经接近 100%其他节点只有 50% 左右。5.2 排查过程从并发数到 KV Cache 分配第一反应是某个请求把上下文拉得太长导致 KV Cache 溢出。但我限制过单请求最大 token 数理论上 32K 上下文不会打满内存。进一步查问题出在“并发请求累积”。llama.cpp 的--parallel参数决定同时处理多少条请求如果设成 4每条请求都有自己的 KV Cache。四台机器切层并行后node2 恰好负责模型靠后的一部分层这部分层的 KV Cache 被所有并发请求共用所以内存压力最大。开了一晚上的服务后node2 的 KV Cache 反复分配、回收内存碎片化越来越严重最后触发了某种退化路径速度就掉到 1.8。我在 llama.cpp 的 verbose 日志里看到大量类似“failed to allocate KV cache”的警告说明问题确实是 KV Cache 分配失败后不断重试导致的。5.3 根因与修复KV Cache 量化和并发限制根因有两个一个是 KV Cache 默认 FP16 太占内存另一个是--parallel设得太大没有和这个模型规模匹配。修复方案很简单我在llama-server启动参数里加上了 KV Cache 量化--cache-type-k q8_0 --cache-type-v q8_0然后把--parallel从 4 降到 2并发请求改为在上层的 API 网关里用排队方式控制。这样一来node2 的内存占比从 99% 降到 65%重新压测 32K 上下文速度回到 7.2 token/s连续跑了两天没有再出现掉速。事后复盘这个问题的本质是“四机切层并行并没有让每台机器的资源需求均等”。模型后半段的层要处理更多经过压缩的上下文信息KV Cache 天然比前半段大所以一旦并发起来某些节点会先于其他节点成为瓶颈。后续可以考虑在切层时手动指定哪台机器负责更多层但这需要更细粒度地了解模型结构不建议新手一上来就折腾。5.4 处理后的效果修复后我又跑了一轮完整测试32K 上下文、2 并发、Q4_K_M 量化、KV Cache q8_0四机集群稳定在 7 token/s 左右。虽然比刚启动时的 7.4 略有下降但这也是真实长期运行的水平。对于 72B 级别模型能达到这个速度已经比我预期好很多毕竟这套硬件并不依赖任何数据中心级的互联技术。这件事也让我养成了一个习惯任何长链路的分布式推理服务都要在启动参数里把 KV Cache 量化默认打开并且对并发数做保守设置。短期看并发开大很快长期看内存碎片化和 KV Cache 膨胀迟早会把速度拉下来。6. 从四机到更大规模的扩展思路6.1 下一级升级RoCE 和多网卡 bonding如果你的目标是继续往上堆机器网络会第一个成为瓶颈。我这次用的是 25GbE RoCE四机规模下够用但到八机、十六机规模时就可能需要考虑多网卡 bonding或者直接上 100GbE。多机切层并行的通信模式是“链式”的每一对相邻节点之间都要传激活值所以网络瓶颈往往出现在连接最密的边上。比较好的做法是把相邻节点两两直连再加一台主干交换机做跨组通信避免所有流量都挤在同一台交换机上。llama.cpp RPC 本身不感知拓扑但通过 IP 规划可以人为控制层分配顺序让通信尽量发生在物理直连的节点之间。6.2 异构集群把 NPU 也拉进来Ryzen AI Max 395 身上还有一个 50 TOPS 的 XDNA 2 NPU我在这次部署中没有深度使用。原因是开源工具链对这块 NPU 的支持还不够成熟大部分推理框架还没有直接调用它的稳定路径。但随着 ONNX Runtime 的 Vitis AI EP 和 ZenDNN 这类库持续更新未来完全有可能把 NPU 作为一个小型专用加速器承接 RPC 服务中的某些算子。到时候的架构可能会变成主节点负责调度和权重分发四个 GPU 切层跑主要推理NPU 专门处理 embedding 或 attention 的一部分计算。这样虽然不能直接提升端到端吞吐但可以降低 CPU 占用提升并发能力。不过这些都是后话当前阶段把 GPU 和 CPU 的协同调好已经能覆盖大多数场景。6.3 我的最终建议与保留观点组这套四机集群我最大的收获不是“速度翻倍”这种数据而是理解了不同并行方式在不同硬件拓扑下的适用边界。如果你也在考虑用 Ryzen AI Max 395 这类 APU 组推理集群我给三条实在的建议模型小于 30B别跨机单机就够了跨机只会增加复杂度和延迟。模型在 70B 到 120B 之间四机切层并行很值得但千万要处理 KV Cache 量化、并发数和网络延迟。模型超过 150B四台 128GB 机器也只能勉强放权重长上下文几乎是奢望这时要考虑把量化等级放到 Q2/Q3或者换更大内存的配置。这套方案不一定适合所有团队毕竟有四台同配置机器本身就不是人人都有的条件。但如果你手头恰好有这么一批 AMD APU 设备与其让它们各自跑些小模型不如按这篇文章的思路尝试把它们抱团。真正把“开源工具链”和“大模型推理优化”结合起来的实践比单机跑分有意思多了。
返回列表