用32块矿卡堆出2TB显存,DIY超级计算机跑vLLM推理 这次我们来看一个相当硬核的 DIY 项目用 32 块 Nvidia CMP170HX 矿卡拼出一台“家用超级计算机”目标是把显存堆到 2TB 级别然后用来跑 vLLM 推理服务。这个思路的本质很简单就是把原本面向专用计算市场的矿卡改造成一张张纯计算卡通过多卡并行凑出超大显存用低成本覆盖大模型推理和高并发场景。这项目最值得关注的点有三个。第一是显存规模2TB 显存在常规单机方案里几乎不可能做到单张 80GB 的 H100 要 25 张才能持平第二是成本CMP170HX 在二手市场的价格和同显存专业卡完全不在一个量级第三是 vLLM 能否在这种“杂牌多卡”上稳定工作这才是整个方案能不能落地的关键。下面我会按“硬件选型 - 驱动/环境 - 部署 vLLM - 功能测试 - API 调用 - 性能观察 - 排错”的顺序把这套方案拆开讲清楚。1. 核心能力速览能力项说明项目类型DIY 多卡推理服务器面向 vLLM 大模型部署核心硬件32 × Nvidia CMP170HX矿卡/计算卡改造总显存目标2TB以 32 卡方案计实际单卡容量需按购买版本确认主要用途本地大模型推理、长文本生成、高并发 API 服务、批量任务启动方式Ubuntu Python 虚拟环境 vllm serve 命令行启动是否支持 API支持vLLM 默认提供 OpenAI 兼容接口是否支持批量任务支持可通过并发请求或批处理脚本实现推荐系统Ubuntu 22.04/24.04不建议 Windows 直接跑 vLLM主要限制矿卡无视频输出、需要机架/转接/电源改造、散热考验大适合读者有一定硬件改造经验、想低成本堆大显存、熟悉命令行部署的开发者从这张表能看出这不是开箱即用的一键包项目而是硬件与软件都要打磨的长期方案。如果你的目标是“买回来就能跑”那直接考虑 4090 或者租云 GPU 更合适如果你追求的是“极限单位显存成本”那这套方案值得认真研究。2. 适用场景与使用边界2.1 适合做什么这套 2TB 显存多卡方案最大的优势是“显存容量”。大模型推理中最贵的资源就是 KV Cache上下文越长、并发数越高KV Cache 占用越大。2TB 显存可以支撑超长上下文测试比如 128K 甚至更长上下文的开源模型不需要频繁做量化压缩。高并发 API 服务在显存充足的情况下vLLM 可以同时处理更多请求吞吐量明显优于 24GB 单卡。多模型常驻不用来回切换模型几个 70B 级别模型可以同时常驻显存。批量离线推理对一批文本、代码或文档做批处理显存够大就不容易 OOM。2.2 不适合做什么大模型训练和全参微调没有 NVLinkPCIe 通信带宽有限训练效率会很低微调也容易受跨卡通信瓶颈影响。图像/视频渲染类任务CMP170HX 本来就是无视频输出的计算卡装进机箱也只是纯算力卡不适合做图形渲染。需要官方质保和稳定业务支持的生产环境矿卡来源、改造成本和故障率都需要自己承担。对功耗和噪音敏感的家庭环境32 张卡的功耗和散热不是普通电脑桌能承受的。2.3 使用边界与合规提醒CMP170HX 属于特殊市场定位的显卡通常以二手或拆机件流通。DIY 过程需要在合规测试环境中进行购买硬件前要确认来源、型号、显存容量和接口规格。项目本身只能用于开发测试、开源模型部署和个人学习不能用于挖矿也不能用未授权数据或模型提供对外服务。涉及模型部署时请优先使用具有明确开源许可证的模型使用自有数据做推理时要做好隐私保护和访问控制。这篇文章讨论的全部内容都以合法采购、合法使用和测试环境验证为前提。3. 环境准备与前置条件3.1 操作系统vLLM 对 Linux 的支持最成熟这套多卡方案建议使用 Ubuntu 22.04 或 Ubuntu 24.04。Windows 下虽然可以通过 WSL 做部分验证但 32 张卡的驱动、CUDA 和 PCIe 设备识别在 Windows 下会非常折腾不建议走这条路。用下面命令确认系统版本lsb_release -a uname -m3.2 GPU 驱动与 CUDACMP170HX 虽然来源特殊但识别方式还是 NVIDIA 驱动那一套。先确认系统能看到多少张卡nvidia-smi -L nvidia-smi --query-gpuindex,name,memory.total --formatcsv如果nvidia-smi没有输出说明驱动没装好或者卡的 PCIe 供电/转接线有问题。建议按 NVIDIA 官方驱动流程安装完成后用nvidia-smi检查每一张卡是否被正确识别。CUDA 版本与 PyTorch、vLLM 的匹配关系需要保持一致。更稳妥的做法是先装好 NVIDIA 驱动再通过 pip 安装匹配的 PyTorch 和 vLLM。3.3 Python 与虚拟环境vLLM 依赖较多强烈建议用虚拟环境隔离不要直接装在系统 Python 里。sudo apt update sudo apt install python3 python3-pip python3-venv -y # 创建虚拟环境 python3 -m venv vllm_env source vllm_env/bin/activate # 可以看到当前 Python 路径已在虚拟环境内 which python3.4 硬件前置检查在跑 vLLM 之前先确认这几点主板和 PCIe 通道够不够32 张卡需要多路 PCIe 转接通常要用矿机主板或带多条 PCIe x16/x1 插槽的服务器主板。电源功率是否足够单张 CMP170HX 的功耗不低32 张卡的整机功耗会非常大需要按单卡功耗总和留足余量。散热风道矿卡多为被动散热或涡轮散热装入机箱后要保证风道能覆盖所有卡。转接线和供电线PCIe 转接线、电源模组线、机架固定件都要提前准备好。如果这些前置条件没准备好后面 vLLM 启动时会出现“识别不到 GPU”“显存不足”“驱动报错”等问题并且很难判断是软件还是硬件导致的。4. 部署 vLLM 与启动服务4.1 安装 vLLM激活虚拟环境后直接安装 vLLM。pip install --upgrade pip pip install vllm安装完成后检查版本python -c import vllm; print(vllm.__version__)如果安装的是最新版本它通常会依赖特定版本的 PyTorch 和 CUDA。可以先让 pip 自动解析依赖遇到版本冲突再单独调整。4.2 确认多卡可用性启动 vLLM 前先用 PyTorch 检查 GPU 是否可以正常访问python -c import torch; print(torch.cuda.device_count()); print(torch.cuda.get_device_name(0))如果打印出的设备数和 32 差距很大说明部分卡没有被正确识别。排查方向一般是 PCIe 转接线是否插稳、供电是否充足、驱动是否识别完整。4.3 启动 vLLM 推理服务vLLM 提供vllm serve命令可以一键启动一个 OpenAI 兼容的推理服务。下面以 Qwen2.5-7B-Instruct 为例启动vllm serve Qwen/Qwen2.5-7B-Instruct \ --tensor-parallel-size 8 \ --gpu-memory-utilization 0.9 \ --max-model-len 32768 \ --port 8000 \ --host 0.0.0.0参数说明--tensor-parallel-size指定使用多少张卡并行切分模型。7B 模型其实用不了 32 卡可以先从 1 卡起步再逐步扩大到 4、8 卡。--gpu-memory-utilization每个 GPU 最多使用的显存比例。0.9 表示预留 10% 显存给 CUDA context避免 OOM。--max-model-len最大上下文长度。显存越大这个值可以调得越大但也要看模型本身支持的窗口长度。--host 0.0.0.0允许局域网内其他机器访问。如果只想本机测试可以用127.0.0.1。如果模型文件还没有下载vLLM 启动时会在~/.cache/huggingface下自动下载模型。下载量可能在十几 GB 到几十 GB 不等首次启动会比较慢。国内网络环境下如果模型下载困难可以改用 ModelScope 下载模型后再用本地路径启动vllm serve /data/models/Qwen2.5-7B-Instruct \ --tensor-parallel-size 8 \ --gpu-memory-utilization 0.9 \ --max-model-len 32768 \ --port 8000具体路径以你下载到的模型位置为准。4.4 验证服务是否启动成功启动日志中如果出现类似下面的信息说明服务已经就绪INFO: Application startup complete. INFO: Uvicorn running on http://0.0.0.0:8000这时打开另一个终端用 curl 访问curl http://127.0.0.1:8000/v1/models如果返回模型列表说明推理服务已经正常启动可以进行下一步测试。5. 功能测试与效果验证5.1 基础文本生成测试先用最简单的请求验证模型能不能正常推理。vLLM 支持 OpenAI 兼容的/v1/chat/completions接口curl http://127.0.0.1:8000/v1/chat/completions \ -H Content-Type: application/json \ -d { model: Qwen/Qwen2.5-7B-Instruct, messages: [ {role: user, content: 用一句话解释什么是 KV Cache} ], max_tokens: 256, temperature: 0.7 }判断标准返回 JSON 中有choices[0].message.content。生成内容没有乱码。没有出现 timeout 或 connection refused。如果能正常返回说明模型加载、前向推理、采样流程都跑通了。5.2 长文本与超长上下文测试2TB 显存方案的重点之一就是长上下文。可以用一段较长的输入文本测试模型的上下文处理能力curl http://127.0.0.1:8000/v1/chat/completions \ -H Content-Type: application/json \ -d { model: Qwen/Qwen2.5-7B-Instruct, messages: [ {role: user, content: 请你阅读下面的长文本然后总结核心观点。} ], max_tokens: 1024, temperature: 0.2 }测试时要重点观察两个地方服务端是否报context length exceeded错误。如果报错说明--max-model-len设置得比输入长度小。nvidia-smi里显存占用是否在输入变长后明显上升。KV Cache 会随输入长度增加而增长。5.3 多并发请求测试vLLM 的核心优势是 PagedAttention 和 Continuous Batching并发请求多时吞吐量仍然能保持稳定。可以用一个简单的 Python 脚本做并发测试import requests import concurrent.futures import time url http://127.0.0.1:8000/v1/chat/completions payload { model: Qwen/Qwen2.5-7B-Instruct, messages: [ {role: user, content: 讲一个关于程序员的笑话。} ], max_tokens: 128, temperature: 0.8 } def call_one(i): try: resp requests.post(url, jsonpayload, timeout120) return i, resp.status_code, len(resp.text) except Exception as e: return i, -1, str(e) start time.time() with concurrent.futures.ThreadPoolExecutor(max_workers32) as executor: results list(executor.map(call_one, range(64))) suc [r for r in results if r[1] 200] fail [r for r in results if r[1] ! 200] print(f成功: {len(suc)}, 失败: {len(fail)}) print(f总耗时: {time.time() - start:.2f}s)判断标准成功数量等于请求总数。没有超时和连接错误。总耗时时长在可接受范围内。如果在高并发下大量请求超时优先检查--max-model-len是否偏大、显存是否被占满、模型服务日志是否有 OOM 报错。5.4 批量任务测试除了并发请求还可以做离线批量任务。准备好一批输入文件例如batch_input/目录下放多个.txt文件然后用脚本逐个读取并调用 vLLM 接口import os import glob import requests import json input_dir ./batch_input output_dir ./batch_output os.makedirs(output_dir, exist_okTrue) url http://127.0.0.1:8000/v1/chat/completions files glob.glob(os.path.join(input_dir, *.txt)) for idx, fp in enumerate(files): with open(fp, r, encodingutf-8) as f: text f.read()[:2000] payload { model: Qwen/Qwen2.5-7B-Instruct, messages: [ {role: user, content: f请对以下内容做摘要\n{text}} ], max_tokens: 512, temperature: 0.3 } try: resp requests.post(url, jsonpayload, timeout180) data resp.json() summary data[choices][0][message][content] out_path os.path.join(output_dir, fresult_{idx}.json) with open(out_path, w, encodingutf-8) as f: json.dump({input: fp, output: summary}, f, ensure_asciiFalse, indent2) print(f[OK] {fp} - {out_path}) except Exception as e: print(f[FAIL] {fp}: {e})批量任务真正跑起来后要关注的是任务队列和失败重试机制。生产环境中建议给每个任务编号记录输入文件、请求时间、返回状态、输出路径失败后自动重试指定次数。6. 接口 API 与批量任务设计6.1 OpenAI 兼容接口说明vLLM 启动后默认提供以下接口GET /v1/models查看当前加载的模型。POST /v1/chat/completions对话补全接口。POST /v1/completions文本补全接口。POST /v1/embeddings部分模型支持 Embedding 接口具体看模型和 vLLM 版本。这套接口标准的好处是原来接 OpenAI SDK 的代码只需要改一下 base_url 就能切换到本地 vLLM 服务。6.2 Python 调用示例from openai import OpenAI client OpenAI( base_urlhttp://127.0.0.1:8000/v1, api_keyEMPTY ) resp client.chat.completions.create( modelQwen/Qwen2.5-7B-Instruct, messages[ {role: user, content: 介绍一下 vLLM 的特点} ], max_tokens512, temperature0.6 ) print(resp.choices[0].message.content)如果安装过openai库这个脚本可以直接运行。6.3 批量任务架构建议对于批量离线任务不建议把几万个请求直接循环发送容易给服务造成压力。更稳妥的方式是把待处理文本拆成若干小任务文件。用少量 worker 并发请求 API。每个任务记录状态pending、running、success、failed。对失败任务做有限次重试。所有输出写入独立目录避免多线程写同一个文件导致覆盖。batch_input/ task_001.txt task_002.txt batch_output/ result_001.json result_002.json logs/ task.log这样即使中途程序崩溃也可以根据日志和结果目录恢复进度。7. 资源占用与性能观察方法7.1 显存占用怎么看vLLM 启动后可以持续用nvidia-smi观察每张卡的显存占用watch -n 1 nvidia-smi重点看两个值Memory-Usage每张卡已经使用的显存。Volatile GPU-Util或UtilizationGPU 计算核心使用率。如果多张卡显存分配不均或者某些卡显存占用明显偏低需要检查--tensor-parallel-size是否设置正确以及 PCIe 通信是否成了瓶颈。7.2 GPU 利用率与卡间通信vLLM 在做 Tensor Parallel 推理时每生成一个 token跨卡通信都会拉高 PCIe 总线占用。CMP170HX 系列没有 NVLink多卡通信完全通过 PCIe这也是这套方案的主要性能瓶颈。观察方法nvidia-smi dmon -s pucvmetpcie相关字段可以看 PCIe 读写速率。如果多卡扩展后吞吐量没有线性提升甚至下降大概率是卡间通信带宽不够。7.3 如何降低显存占用如果显存不足或想塞下更多模型可以考虑降低--gpu-memory-utilization从 0.9 降到 0.7。减小--max-model-len例如从 32768 降到 16384。使用量化模型比如 AWQ、GPTQ 量化版模型。使用--enforce-eager关闭 CUDA Graph但会降低推理性能需要根据实际表现取舍。对超大模型用小 batch 并发避免瞬时 KV Cache 暴涨。7.4 如何避免端口冲突和进程残留vLLM 默认监听 8000 端口。如果之前启动过服务再次启动前先确认端口没有被占用ss -lntp | grep 8000如果端口被占用可以换端口启动vllm serve Qwen/Qwen2.5-7B-Instruct --port 8001已经启动但想要停止的 vLLM 服务找到 PID 后正常结束ps aux | grep vllm kill PID不要频繁用kill -9可能导致缓存文件和进程残留。8. 常见问题与排查方法问题现象可能原因排查方式解决方案nvidia-smi 看不到部分显卡供电不足、PCIe 转接线松动、驱动未完整加载检查 PCIe 物理连接查看系统日志重新插拔转接线检查电源功率和模组线vLLM 启动报 CUDA out of memory显存被其他进程占用或模型加载所需显存超过单卡容量nvidia-smi 检查空闲显存关闭其他进程调整 gpu-memory-utilization使用量化模型模型下载速度慢或失败网络问题或模型仓库连接超时检查网络确认模型名称拼写使用国内模型源下载后改为本地路径启动请求返回 context length exceeded输入长度超过 max-model-len检查输入文本长度调大 --max-model-len或截断输入文本并发请求超时显存不足、模型过大、并发数过高查看服务日志和显存状态降低并发数减小 max-model-len增加 batch 调度参数多卡扩展后性能不升反降卡间通信带宽不足用性能监控查看 PCIe 读写减少 tensor-parallel-size优先用 4 卡或 8 卡并行Python 依赖安装冲突vLLM 和 PyTorch 版本不匹配查看 pip 报错信息单独创建虚拟环境按 vLLM 官方要求安装对应版本调用 OpenAI SDK 报 404base_url 配置错误检查接口路径确保 base_url 以/v1结尾这些问题是多卡 vLLM 部署中最常见的几类。遇到问题时先看日志再查硬件不要直接重装系统。9. 最佳实践与使用建议9.1 先单卡验证再逐步扩展第一次部署不要直接上 32 卡。先用--tensor-parallel-size 1跑通 7B 模型确认驱动、依赖、接口都没问题后再逐步扩展到 4 卡、8 卡。这样定位问题会容易很多。9.2 保留一套最小可运行配置把验证过的关键命令和配置保存下来最好是写成脚本。例如# start_vllm.sh #!/bin/bash source /opt/vllm_env/bin/activate vllm serve Qwen/Qwen2.5-7B-Instruct \ --tensor-parallel-size 8 \ --gpu-memory-utilization 0.9 \ --max-model-len 32768 \ --port 8000以后重启服务直接执行脚本避免记错参数。9.3 输入、模型、输出分目录管理模型文件、输入素材、输出结果不要混在一起。推荐结构/home/user/vllm-lab/ models/ inputs/ outputs/ logs/ scripts/模型文件用models/单独存放批量任务输入放inputs/生成结果放outputs/这样不会边跑边找文件。9.4 批量任务要加日志和失败重试批量任务一旦跑起来大概率会碰到网络抖动、模型超时、显存暂时不足等问题。日志和重试机制不是可选项而是必选项。每个任务记录状态失败重试最多 3 次重试间隔可以指数退避。9.5 接口服务要限制访问范围虽然 vLLM 本身没有复杂的鉴权体系但暴露在局域网或公网时要非常小心。建议只在可信内网访问不要直接绑定0.0.0.0暴露公网。如果需要对外开放放在 Nginx 等反向代理后面并增加访问控制。不要用默认的api_keyEMPTY对外提供服务。9.6 合规与授权提醒涉及模型权重下载、数据集使用、生成内容对外发布时必须确认模型许可证是否允许商用或二次分发。输入数据是否包含个人隐私或敏感信息。生成内容是否可能涉及版权、肖像权、名誉权。如果是二手或来源不明硬件要确认硬件来源合法。这套方案从硬件到模型全部在测试环境中验证不要用于任何违规用途。10. 总结与下一步CMP170HX 多卡改造方案的核心价值是用低成本换大显存给 vLLM 大模型推理提供了非常广阔的试验场。2TB 显存意味着你可以同时常驻多个大模型也可以用超大上下文做文档分析和批量推理。这个方向最适合对硬件改造和命令行部署都有经验的开发者。最开始验证时建议先跑通 7B 模型单卡然后扩展到 8 卡测试tensor-parallel-size的效果最后再上 32 卡满配并观察卡间通信和显存分配整个过程按“软件先行、硬件扩展”的顺序推进。最容易踩的坑集中在三个地方供电和转接导致部分卡掉线、PCIe 通信带宽撑不起大规模并行、以及模型下载源不稳定。这三个问题只要在规划阶段提前准备好后面的部署会顺畅很多。下一步可以继续折腾的方向包括测试 AWQ/GPTQ 量化模型在这个显存规模下的并发能力、在同一套机器上部署多个不同尺寸的模型、把批量任务改成完整的任务队列并接入异步处理框架或者把接口服务接到自己的业务系统里做成一个家庭级 AI 推理网关。这套方案的实验属性很强但能跑通的东西确实不少建议收藏备用。