四台Ryzen AI Max+ 395搭建本地大模型推理集群实战
2026/9/19 3:15:59 网站建设 项目流程

1. 为什么是四台Ryzen AI Max+ 395,而不是一台“大机器”

1.1 先看懂这颗APU的真实定位

手头有四台搭载AMD Ryzen AI Max+ 395的小主机时,很多人第一反应是拿来打游戏或者当软路由,但这颗芯片真正值钱的地方不在游戏,而在于它把“大内存”和“较强核显”揉在了一起,非常适合做本地大模型推理。

简单过一遍规格:Ryzen AI Max+ 395是Strix Halo平台里的顶配,CPU部分是16核32线程的Zen 5,GPU部分是40个RDNA 3.5计算单元的Radeon 8060S核显,还有一块50 TOPS的XDNA 2 NPU。最核心的是它支持最高128GB的LPDDR5X统一内存,位宽256-bit,带宽大约256GB/s。这里的关键词是“统一内存”:GPU不再有独立显存,CPU和GPU共享同一块物理内存,权重加载不需要做任何跨PCIe拷贝,直接把模型常驻在内存里就能跑。

这个架构和传统GPU服务器是完全不同的逻辑。传统NVIDIA显卡靠的是超高显存带宽,一张RTX 4090带宽超过1TB/s,但显存只有24GB,70B模型塞不进去;A100/H100带宽到3TB/s,价格也是天价。APU这条路线反过来了:带宽不算夸张,但容量管够,128GB单机就能装下70B甚至更大模型的量化权重。代价就是推理速度受制于256GB/s这个内存带宽,所以优化思路要从“省显存”变成“省带宽”,这一点后面会反复提到。

1.2 四机集群能解决哪些单机解决不了的问题

单机128GB内存看起来很大,但实际使用中很快会碰到瓶颈。我自己实测下来,70B模型做成Q4量化,权重大概40GB,加上KV Cache和运行时开销,单机确实能跑,但decode速度大概只有6到8 token/s,属于能用的水平。更难受的是并发:一旦多个请求同时进来,vLLM把它们打包成一个batch,每个token生成都要把所有权重从头到尾读一遍,带宽共享之后,单路速度会被拖得更低。

四台机器组成集群之后,解决的就不是“能不能跑”的问题,而是“怎么跑得稳、跑得多”:

  • 吞吐扩展:把同一个模型复制到4台机器上,用负载均衡把请求分散出去,整体吞吐接近4倍,每路的响应速度也不会互相干扰。
  • 跨节点跑超大模型:70B的FP16权重大约140GB,单机放不下,但4台机器用张量并行把权重切开,每台只需要35GB,就能跑更高精度的版本。
  • 多模型隔离:集群里可以拆开用,一台跑70B主模型,一台跑32B快速模型,一台跑embedding和rerank,互不抢占。
  • 可用性兜底:负载均衡层做健康检查,某台机器挂了自动摘除,剩余三台继续服务,这在个人和团队场景里是非常实用的“故障转移”能力。

所以我这套集群的定位不是“跑分工具”,而是一个轻量、可控、成本可接受的大模型服务基础设施。

2. 平台选型:网络、存储与开源工具链怎么搭配

2.1 网络与存储:先算清楚瓶颈再买设备

搭建集群最容易犯的错是一上来就买设备,实际上应该先算瓶颈。这四个节点的内部计算路径是这样的:模型权重存在LPDDR5X内存里,GPU读取时走256GB/s的内存总线;如果只用单机推理,机器之间完全不需要通信,网络只负责接收请求和返回结果。这种情况下千兆网络都够用。

但一旦要跨节点做张量并行,情况就不一样了。每个token生成时,各节点上的计算单元需要把中间结果做all-reduce,这个数据量跟模型规模、并行度强相关。可以这么理解:单机读内存是256GB/s,如果跨节点每台只处理四分之一权重,但每次都要把结果汇总,那节点间通信速率如果低于内存带宽,通信就会成为新瓶颈。我的建议是:

  • 如果主要做数据并行(每台机器独立跑完整模型),万兆以太网足够。
  • 如果打算做4节点张量并行,至少25GbE起步,最好上支持RoCE的网卡,并且要开启流控和ECN。
  • InfiniBand对这个平台来说有些“杀鸡用牛刀”,Ryzen AI Max+ 395本身没有原生IB支持,要靠PCIe扩展卡,成本直接翻倍,收益对256GB/s带宽的APU来说并不明显。

存储方面不需要上Ceph这类分布式存储,太重了。四台机器只需要一份模型权重,最简单的方式是选一台做NFS服务端,其他节点挂载同一个目录;或者更省事一点,直接写好rsync脚本,把权重同步到每台机器本地。实测下来,NFS在加载模型时会有一次性的网络读取开销,运行期因为权重已经常驻内存,基本没有额外IO,所以两种方案都能接受。

2.2 工具链分工:每个开源组件干自己最擅长的活

集群方案里涉及的开源工具链看起来很多,其实分工很清楚,不用全部自己写胶水代码。

操作系统和驱动层我用的是Ubuntu 22.04 LTS加ROCm 6.x,这是目前AMD平台上兼容性最稳的组合。ROCm相当于AMD版的CUDA,PyTorch推理要跑在GPU单元上就必须有它。PyTorch本身直接用官方ROCm构建版本,不要自己去编,太折磨人。

推理引擎最核心的是vLLM。它天然支持PagedAttention、Continuous Batching、Prefix Caching这些优化,而且有ROCm分支的wheel包,直接安装就能用。vLLM做多节点并行时依赖Ray来调度,Ray负责在四台机器上拉起分布式worker,vLLM负责模型切分和推理。所以Ray在这里不是可有可无的组件,而是vLLM跨节点的“搬运工”。

负载均衡我用了最简单的Nginx stream模块做四副本轮询,配置量很小,但效果很稳定。监控侧用rocm-smi做命令行快速检查,再用Prometheus加Grafana做可视化,rocm_exporter能把GPU温度、功耗、显存占用暴露成metrics,比手动敲命令强得多。

2.3 为什么不上Kubernetes或Hadoop那套重型方案

每次说到集群,总会有人问为什么不用Kubernetes。我的理由很实际:四台机器跑K8s,光是控制面组件就要吃掉不少内存和CPU,而这个平台的CPU资源虽然不弱,但对推理场景并不是最关键的资源。更重要的问题是,K8s对AMD APU这种统一内存设备的设备调度支持并不完善,你不能简单地把nvidia.com/gpu那套逻辑照搬过来,需要自己写device plugin,得不偿失。

Hadoop、Spark、Kafka这类大数据组件跟LLM推理更是两码事。大数据集群处理的是“数据分片+分布式计算”,关心的是吞吐和容错;LLM推理服务关心的是“请求排队+显存管理+token生成延迟”。这是完全不同的调度模型,硬套只会增加复杂度。四台机器用Ray加Nginx的组合,已经覆盖了资源调度、服务发现、负载均衡和健康检查这些核心需求,复杂度刚好够用。

3. 四机集群搭建实操:从裸机到多节点推理

3.1 系统、BIOS与ROCm环境一次过

先说BIOS。Ryzen AI Max+ 395小主机出厂时GPU可用的“显存”大小设置往往比较保守,如果你不在BIOS里调整,系统可能只给GPU分配一部分内存。我的做法是进入BIOS,找到UMA Frame Buffer Size或者类似的GPU内存配置项,固定给GPU分配96GB,剩余32GB留给操作系统和运行时。给太多会导致系统内存紧张,给太少模型装不下,96GB这个值在跑70B量化模型时比较均衡。

系统装完后第一件事是加用户组权限,否则后续调用GPU设备会报权限错误:

sudo usermod -aG render,video $USER

然后安装ROCm驱动。我建议直接用官方安装器:

sudo apt update sudo apt install amdgpu-dkms sudo reboot

重启后验证是否识别到设备:

rocm-smi rocm-smi --showmeminfo vram

正常能看到设备列表和显存容量信息。接下来是Python环境的安装,这里要特别小心版本匹配。PyTorch必须用ROCm对应的wheel包,我用的是ROCm 6.x版本:

pip install torch --index-url https://download.pytorch.org/whl/rocm6.2

装完之后先做个快速验证:

python -c "import torch; print(torch.cuda.is_available(), torch.cuda.device_count())"

ROCm下PyTorch的API仍然沿用cuda命名,所以看到True4就说明驱动工作正常。最后装vLLM的ROCm版:

pip install vllm-rocm

vLLM安装包比较大,如果网络不稳定建议提前配好镜像源。

3.2 配置Ray集群并验证多机通信

四台机器我分别命名node1到node4,把它们的IP写进每台机器的/etc/hosts,避免DNS解析超时。防火墙方面要放行Ray的6379端口、8265面板端口,以及vLLM服务用的8000端口。

在node1上启动head节点:

ray start --head --port=6379 --dashboard-host=0.0.0.0

在其余三台机器上执行:

ray start --address=node1:6379

回到node1上看集群状态:

ray status

如果看到4个节点、每个节点都有CPU资源,说明Ray集群组好了。这里有个小细节:如果你并不希望Ray把所有CPU核都拿去跑任务,可以在启动参数里加--num-cpus限制一下,给系统留出余量。

3.3 启动跨节点vLLM服务

我用来测试的主模型是Qwen2.5-72B-Instruct的safetensors量化版本,下载到NFS共享目录后,所有节点都能访问。在Ray的head节点上启动vLLM,它会自动通过Ray把张量并行worker调度到四台机器上:

python -m vllm.entrypoints.openai.api_server \ --model /data/models/Qwen2.5-72B-Instruct-GPTQ-Int4 \ --tensor-parallel-size 4 \ --max-model-len 8192 \ --gpu-memory-utilization 0.85 \ --port 8000 \ --served-model-name qwen2.5-72b

启动日志里如果看到类似“rank 0, rank 1, rank 2, rank 3”初始化的信息,说明多节点通信已经打通。模型加载完成后用curl验证:

curl http://node1:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{"model":"qwen2.5-72b","messages":[{"role":"user","content":"你好"}],"max_tokens":50}'

能正常返回内容,跨节点推理就基本跑通了。

3.4 轻量负载均衡与故障转移

跨节点TP只是能力验证,日常对外服务我更推荐四副本加负载均衡的架构。每台机器各跑一个单机vLLM实例,模型相同,然后在一台机器上用Nginx做TCP层转发。这里用stream模块而不是http模块,因为vLLM的OpenAI接口本质是HTTP,但stream转发更省心,直接按端口转:

stream { upstream llm_backend { server node1:8000; server node2:8000; server node3:8000; server node4:8000; } server { listen 8000; proxy_pass llm_backend; } }

然后在每台vLLM实例上开启健康检查接口,/health路径返回200 OK。Nginx本身有被动健康检查,配合脚本定时探测,某台机器宕机后会自动从upstream里摘除,等恢复后再加回来。这一套做下来就是最轻量的“故障转移”方案,不需要引入额外的注册中心。

4. 大模型推理优化:带宽、量化与并行策略

4.1 理解APU推理的核心瓶颈:带宽优先于算力

在传统GPU上优化推理,首先关注的是显存容量、算力利用率、算子融合。但在Ryzen AI Max+ 395上,优先级完全不同。它最大的瓶颈不是GPU算力,而是256GB/s的内存带宽。为什么会这样?因为自回归生成每个token时,理论上需要把模型的所有权重从内存读一遍,读得越快,生成越快。我经常用这个公式估算上限:

理论最高速度 ≈ 内存带宽 / 每token需要读取的权重字节数

拿70B模型来说,FP16权重约140GB,理论速度只有256/140,约1.8 token/s;如果量化成Q8,权重约70GB,理论速度约3.6 token/s;量化成Q4,权重约40GB,理论速度约6.4 token/s。所以在这个平台上,量化带来的收益是立竿见影的,优先级比任何算子优化都高。

我实际用的模型是GPTQ-Int4量化版,整个加载后显存占用约40多GB。在做DP模式时,单机可以稳定跑到5到7个token/s的实测速度,和理论估算基本吻合。如果每个请求并发上来,单机总吞吐会提高,但单个用户感受到的速度会下降,这也是我在开头说“并发一上来自找麻烦”的原因。

4.2 KV Cache与并发参数怎么算

KV Cache是vLLM这类推理引擎能高并发服务的根本原因,但它也吃内存。很多人只看模型权重大小,却忘了KV Cache会把内存占满。KV Cache大小的估算公式并不难:

KV Cache字节数 = 2 × 层数 × KV头数 × 每个头的维度 × 2字节 × 序列长度

以Qwen2.5-72B为例,64层,8个KV头,每个头维度128,FP16精度下每个token大约占用256KB。算一下:

2 × 64 × 8 × 128 × 2 = 262144 字节 ≈ 256KB/token

那么8K上下文需要2GB,32K上下文需要8GB,128K上下文需要32GB。这个数字对推理服务来说很关键,因为你设置--max-model-len越长,KV Cache预留就越大,留给权重的空间就越少。

实际操作里我的建议是:

  • 明确业务需要多长上下文,不要无脑开长文本。
  • --max-model-len 8192对大多数内部工具链已经够用。
  • --gpu-memory-utilization不要设到0.95,APU是统一内存,系统进程也要吃内存,设0.85比较安全。
  • --max-num-seqs控制并发批大小,APU带宽有限,设太大反而让单路延迟不可控,8到16是合理区间。

vLLM的Prefix Caching也建议开启,它会把公共前缀的KV Cache缓存下来,比如system prompt相同的情况下,后续请求可以直接复用,省掉的重复计算非常可观。

4.3 TP、DP、PP怎么选:跨节点并行策略的取舍

并行策略的选择直接影响集群性能,这里我把三种并行方式的实际体感都试了一遍。

张量并行是vLLM跨节点支持最完善的方式。它把权重切到不同节点,每个节点只算一部分,适合单个模型超过单机内存的场景。缺点也很明显:每生成一个token,各节点都要做一次全量all-reduce,通信量很大。我在万兆网络下跑TP=4,单token生成速度反而不如单机Q4版本,因为网络延迟和带宽严重拖了后腿。所以如果要做跨节点TP,网络必须是25GbE起步,并且要调好RoCE流控,否则收益会被通信吃光。

数据并行是我最终留下的方案。每台机器独立跑一份模型,请求通过Nginx轮询分发,机器之间几乎没有通信开销。它的要求是模型权重加KV Cache必须单机放得下。70B Q4在128GB统一内存上完全没压力,所以DP是这个平台的“最优解”。实测4副本时,总吞吐接近单机的4倍,而且任何一台宕机都不会影响其他节点。

流水线并行是把模型按层切成几段,机器之间只传激活值,通信量比TP小,但会有流水线气泡,请求延迟会变高。vLLM对多层PP的支持也相对有限,我在这个场景里没有继续深挖。我的建议很直接:能DP就DP,模型大到单机放不下再考虑TP,并且先把网络升级到25GbE以上。

4.4 监控与持续调优

集群搭好之后不是一劳永逸,需要持续观察几个关键指标。

最简单的工具是rocm-smi,直接看每一台机器的GPU占用、显存、温度和功耗:

rocm-smi --showmeminfo vram rocm-smi --showtemp --showpower

vLLM自带的/metrics接口能暴露吞吐量、排队请求数、平均decode时延,这些数据能直接反映服务的健康度。我把这些指标接入了Prometheus和Grafana,设置了一个简单告警:当请求排队数超过50或单路decode时延超过3秒时,说明后端已经开始过载,需要扩容副本或降低并发。

还有一个功耗上的实测体会:Ryzen AI Max+ 395的TDP可以从CPU和GPU之间动态分配,推理时真正吃满的往往是内存带宽和GPU单元,CPU核心反而比较闲。我把BIOS里的TDP从120W降到90W,decode速度几乎没变,但整机温度和风扇噪音明显下降。如果机器放在办公室环境,这个调优值得做。

5. 踩坑实录:问题排查思路与速查表

5.1 几个典型的ROCm与vLLM问题

搭建过程中我踩过不少坑,挑几个最典型的写在这里。

第一个坑是PyTorch识别不到GPU。表现是torch.cuda.is_available()返回False。排查路径一般是先跑rocm-smi,如果能正常显示设备,说明驱动没问题,那大概率是当前用户不在render组或video组里,用前面提到的usermod命令加权限后重新登录即可。如果rocm-smi本身报错,那就是内核模块没加载,重启或者重新安装amdgpu-dkms

第二个坑是vLLM多节点启动时长时间卡住,日志停留在RCCL初始化阶段。这是因为四台机器通信失败。我遇到的原因有两个:一是防火墙没有放行Ray的随机端口,二是默认网卡选择错误。解决办法是显式指定NCCL通信网卡,并关闭不必要的IB检测:

export NCCL_SOCKET_IFNAME=eth0 export NCCL_IB_DISABLE=1 export NCCL_DEBUG=INFO

设置完再启动,日志里能看到具体的通信地址,排查就清晰了。

第三个坑是OOM。现象是vLLM启动时报显存不足,但系统free内存还有很多。这通常不是真的内存不够,而是UMA Frame Buffer分配得太少,或者--gpu-memory-utilization设得过高导致vLLM计算预期容量时超过了驱动给定的容量限制。解决方法是先确认BIOS里GPU显存分配值,再下调utilization参数到0.8左右。

第四个坑和模型格式有关。vLLM对GGUF格式的支持度不如llama.cpp,如果你下载的模型是GGUF格式,很可能会在加载阶段报算子不支持。我的建议是尽量下载safetensors格式或者GPTQ、AWQ量化格式,这些在vLLM生态里兼容性最好。

5.2 常用问题排查速查表

这里整理一份速查表,遇到问题可以直接对号入座:

现象可能原因处理方式
rocm-smi无输出或看不到设备amdgpu驱动未加载/内核模块异常重装amdgpu-dkms,重启后`lsmod
torch.cuda.is_available()返回False用户不在render/video组执行sudo usermod -aG render,video $USER后注销重登
vLLM多节点启动卡在RCCL阶段防火墙未放行、网卡选择错误放行端口,设置NCCL_SOCKET_IFNAMENCCL_IB_DISABLE=1
4节点TP速度比单机还慢网络带宽不足,TP通信开销过大升级25GbE网络,或者改用DP方案
系统看起来内存充足但模型OOMUMA Frame Buffer分配不足BIOS里调大GPU显存分配,降低utilization
模型GGUF格式加载失败vLLM对GGUF支持有限换safetensors/GPTQ/AWQ格式
多副本负载不均衡Nginx默认轮询没有考虑后端延迟差异调整权重或换成最少连接模式,同时观察metrics

5.3 实测效果与这套方案的边界

最后说一下这台集群的最终形态和我对它的评价。我目前用的是四副本DP方案,每台机器跑Qwen2.5-72B的GPTQ-Int4版本,对外由Nginx统一入口。单机实测约6 token/s,四机整体吞吐约24 token/s左右,这个数字和消费级单卡大显存方案比并不算惊艳,但胜在稳定、可预测、成本可控,而且四台机器可以独立维护,重启任何一台都不影响整体服务。

这套方案的边界也很清楚:第一,它不适合追求极低延迟的场景,单token延迟受内存带宽制约,很难突破;第二,它不适合需要超大上下文的高并发场景,KV Cache会吃光内存,导致可用并发下降;第三,这套集群的优化空间基本被内存带宽锁死,想靠堆软件来绕过,效果有限。

对我来说,它的价值在于用相对低的成本,让一个团队或一个资深开发者拥有了一套全栈开源、可自由定制的大模型私有推理服务,这对内部工具链搭建和产品原型验证来说,已经足够实用了。如果后续模型继续变大,我会优先考虑更激进的量化方案,而不是继续增加节点数。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询