1. 项目概述
最近在为企业内部构建AI推理服务时,我选择了NVIDIA DGX Spark作为硬件平台,搭配SGLang推理引擎和LiteLLM API网关,部署了Qwen3.5-35B-A3B-FP8大模型。这套方案特别适合需要在本地部署开源大模型、同时为公司内部多个团队提供统一AI服务接口的场景。
1.1 核心需求解析
企业级AI推理服务有几个关键需求:
- 数据安全:模型和业务数据必须完全留在内网
- 统一接口:不同团队和工具能使用标准API接入
- 性能稳定:需要支持高并发和长上下文
- 易于管理:要有完善的用户权限和用量监控
传统方案通常直接在GPU服务器上部署单一模型服务,但这存在几个问题:
- 缺乏统一的API网关,每个模型需要单独对接
- 没有用户认证和配额管理
- 故障恢复和负载均衡能力弱
2. 硬件选型与架构设计
2.1 NVIDIA DGX Spark硬件优势
我们选用了两台NVIDIA DGX Spark工作站,这是NVIDIA 2025年推出的桌面级AI工作站,主要配置:
- Grace Blackwell GB10超级芯片:ARM aarch64架构
- 128GB LPDDR5x统一内存:CPU和GPU共享,远超传统GPU的24GB/48GB显存限制
- 273GB/s内存带宽:对大型语言模型推理至关重要
- 1 PFLOP FP4算力:支持高效的FP8推理
- 4TB NVMe存储:足够存放多个大型模型
特别值得一提的是统一内存架构。传统GPU方案中,当模型参数超过显存时,需要复杂的流水线调度和内存交换,严重影响性能。而DGX Spark的128GB统一内存可以完整加载35B参数的Qwen3.5模型,避免了这类问题。
2.2 为什么选择MoE架构的Qwen3.5-35B-A3B
在模型选型上,我们对比了几种主流开源模型后,最终选择了Qwen3.5-35B-A3B,这是一个混合专家(MoE)模型:
- 总参数35B,但每个token仅激活约3B参数
- FP8量化后约17GB,DGX Spark内存轻松容纳
- Apache 2.0许可证,企业商用无忧
- MMLU-Pro 85.3分,超越GPT-5-mini
- SWE-bench 69.2分,编码能力突出
关键性能考量:DGX Spark的273GB/s内存带宽,对于Dense模型来说,解码阶段每生成一个token都要读取全部激活权重。27B Dense模型需要读取约28GB,理论极限约10tok/s;而MoE 3B激活只需读取3-4GB,理论极限可达60-70tok/s,速度差距高达7倍。
2.3 整体架构设计
我们的三层架构设计如下:
code复制公司内部用户(浏览器/IDE插件/API调用)
│
▼
┌───────────────────────────────┐
│ Linux虚拟机(4C/8G,无需GPU) │
│ LiteLLM Proxy (:4000) │ ← 统一入口,OpenAI兼容API
└──────────┬────────────────────┘
│ ┌──────────────────────┐
│ │ PostgreSQL数据库 │
│ 根据model路由 │ (存储用户Key、用量统计)│
┌─────┼─────┐ └──────────────────────┘
▼ ▼
DGX Spark 1 DGX Spark 2
SGLang :30000 SGLang :30000
(Qwen3.5-35B-A3B-FP8)
这种设计的优势在于:
- 资源隔离:网关层不占用GPU资源
- 弹性扩展:新增Spark节点只需修改配置
- 数据安全:使用企业现有数据库实例
3. SGLang推理服务部署
3.1 环境准备与验证
首先确认硬件环境符合要求:
bash复制# 确认GPU和驱动版本
nvidia-smi
# 预期输出:
# NVIDIA GB10, Driver 580.x, CUDA 13.0
DGX Spark是ARM aarch64架构,必须使用对应的Docker镜像:
bash复制docker pull lmsysorg/sglang:dev-cu13
选择dev-cu13标签而非spark标签的原因:
spark是早期稳定版,不支持Qwen3.5- Qwen3.5支持在2026年2月才合入SGLang(PR #18489)
dev-cu13包含CUDA 13支持的最新开发版
3.2 模型下载与准备
创建模型目录并下载Qwen3.5:
bash复制mkdir -p ~/models
# 从HuggingFace下载
sudo apt install git-lfs && git lfs install
git clone https://huggingface.co/Qwen/Qwen3.5-35B-A3B-FP8 ~/models/Qwen3.5-35B-A3B-FP8
# 国内用户可从ModelScope下载(速度更快)
git clone https://www.modelscope.cn/Qwen/Qwen3.5-35B-A3B-FP8.git ~/models/Qwen3.5-35B-A3B-FP8
3.3 启动SGLang服务
使用以下命令启动容器:
bash复制docker run -d \
--name sglang-qwen35 \
--gpus all \
--privileged \
--restart unless-stopped \
-p 30000:30000 \
-v ~/models:/models \
--ipc=host \
--shm-size 32g \
-e TRITON_CACHE_DIR=/tmp/triton_cache \
lmsysorg/sglang:dev-cu13 \
sglang serve \
--model-path /models/Qwen3.5-35B-A3B-FP8 \
--served-model-name Qwen3.5-35B-A3B-FP8 \
--host 0.0.0.0 \
--port 30000 \
--tp-size 1 \
--trust-remote-code \
--attention-backend triton \
--linear-attn-backend triton \
--fp8-gemm-backend triton \
--mem-fraction-static 0.80 \
--context-length 262144 \
--reasoning-parser qwen3 \
--tool-call-parser qwen3_coder
关键参数说明:
| 参数 | 值 | 说明 |
|---|---|---|
--privileged |
- | 授权容器执行Triton JIT编译,否则会报operation not permitted |
--attention-backend |
triton | Qwen3.5的GDN架构仅支持triton、trtllm_mha、fa4三种后端 |
--fp8-gemm-backend |
triton | 解决Qwen3.5-FP8的scale格式与DeepGEMM不兼容问题 |
--mem-fraction-static |
0.80 | 80%可用内存分配给KV Cache |
TRITON_CACHE_DIR |
/tmp/triton_cache | 确保Triton缓存目录可写 |
3.4 服务验证与测试
等待模型加载完成(约3-5分钟),查看日志:
bash复制docker logs -f sglang-qwen35
# 看到"The server is fired up and ready to roll!"表示启动成功
测试推理接口:
bash复制curl -X POST http://localhost:30000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen3.5-35B-A3B-FP8",
"messages": [{"role": "user", "content": "你好,请介绍一下自己"}],
"max_tokens": 200
}'
3.5 部署中的关键问题与解决
在实际部署中,我们遇到了几个典型问题:
-
DeepGEMM崩溃:
Unknown recipe- 原因:Qwen3.5-FP8的scale格式不是DeepGEMM期望的
ue8m0 - 解决:使用
--fp8-gemm-backend triton绕过DeepGEMM
- 原因:Qwen3.5-FP8的scale格式不是DeepGEMM期望的
-
Triton权限问题:
operation not permitted- 原因:Docker默认安全策略阻止Triton JIT编译
- 解决:启动时加
--privileged参数
-
注意力后端不兼容
- Qwen3.5使用GDN混合注意力架构
- 根据SGLang文档,Blackwell上仅支持
triton、trtllm_mha、fa4三种后端
-
Dense与MoE的速度差异
- 实测Qwen3.5-27B(Dense)仅7.25tok/s
- 换成35B-A3B(MoE)后速度提升至约60tok/s
4. LiteLLM网关部署
4.1 数据库准备
使用公司现有PostgreSQL实例:
sql复制CREATE DATABASE litellm;
4.2 配置文件编写
创建/data/litellm/config.yaml:
yaml复制model_list:
- model_name: qwen3.5-35b
litellm_params:
model: openai/Qwen3.5-35B-A3B-FP8
api_base: http://10.10.91.153:30000/v1 # DGX Spark 1
api_key: "none"
model_info:
input_cost_per_token: 0
output_cost_per_token: 0
- model_name: qwen3.5-35b
litellm_params:
model: openai/Qwen3.5-35B-A3B-FP8
api_base: http://10.10.91.154:30000/v1 # DGX Spark 2
api_key: "none"
router_settings:
routing_strategy: least-busy
num_retries: 2
timeout: 300
allowed_fails: 3
cooldown_time: 60
general_settings:
master_key: sk-your-master-key-change-me
database_url: "postgresql://postgres:yourpassword@10.10.91.224:5432/litellm"
litellm_settings:
set_verbose: false
json_logs: true
request_timeout: 600
4.3 Docker Compose部署
创建/data/litellm/docker-compose.yaml:
yaml复制version: "3.9"
services:
litellm:
image: docker.litellm.ai/berriai/litellm:main-stable
container_name: litellm-proxy
restart: unless-stopped
ports:
- "4000:4000"
volumes:
- ./config.yaml:/app/config.yaml
environment:
- LITELLM_MASTER_KEY=sk-your-master-key-change-me
- DATABASE_URL=postgresql://postgres:yourpassword@10.10.91.224:5432/litellm
command:
- "--config"
- "/app/config.yaml"
- "--port"
- "4000"
启动服务:
bash复制cd /data/litellm
docker compose up -d
4.4 网关功能验证
健康检查:
bash复制curl http://localhost:4000/health \
-H "Authorization: Bearer sk-your-master-key-change-me"
# 预期:healthy_count: 2, unhealthy_count: 0
测试聊天接口:
bash复制curl -X POST http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-your-master-key-change-me" \
-d '{
"model": "qwen3.5-35b",
"messages": [{"role": "user", "content": "你好,请介绍一下自己"}],
"max_tokens": 500
}'
5. 用户与团队管理
5.1 创建团队
bash复制curl -X POST http://localhost:4000/team/new \
-H "Authorization: Bearer sk-your-master-key-change-me" \
-H "Content-Type: application/json" \
-d '{
"team_alias": "dev-team",
"models": ["qwen3.5-35b"],
"rpm_limit": 100
}'
# 记录返回的team_id
5.2 生成成员API Key
bash复制curl -X POST http://localhost:4000/key/generate \
-H "Authorization: Bearer sk-your-master-key-change-me" \
-H "Content-Type: application/json" \
-d '{
"team_id": "<team_id>",
"key_alias": "zhangsan-key",
"models": ["qwen3.5-35b"]
}'
5.3 客户端接入示例
Python SDK使用:
python复制from openai import OpenAI
client = OpenAI(
base_url="http://<网关IP>:4000/v1",
api_key="sk-zhangsan-的-key"
)
response = client.chat.completions.create(
model="qwen3.5-35b",
messages=[{"role": "user", "content": "用Python实现快速排序"}],
max_tokens=2048,
)
print(response.choices[0].message.content)
6. 运维与监控
LiteLLM提供了Web管理界面,访问:
code复制http://<网关IP>:4000/ui
使用master_key登录后可以:
- 查看各模型健康状态
- 监控API调用量
- 管理团队和Key
- 设置预算和速率限制
7. 扩展方案
7.1 增加Spark节点
只需在config.yaml中追加新条目:
yaml复制 - model_name: qwen3.5-35b
litellm_params:
model: openai/Qwen3.5-35B-A3B-FP8
api_base: http://10.10.91.155:30000/v1 # 新增Spark 3
api_key: "none"
7.2 接入多种模型
部分Spark节点可部署不同模型:
yaml复制 - model_name: qwen3-coder
litellm_params:
model: openai/Qwen3-Coder-Next-FP8
api_base: http://10.10.91.155:30001/v1
api_key: "none"
客户端只需修改model字段即可切换模型。
7.3 云端Fallback
本地节点故障时自动切换到云端:
yaml复制 - model_name: qwen3.5-35b
litellm_params:
model: moonshot/kimi-k2.5
api_key: "os.environ/MOONSHOT_API_KEY"
8. 实际应用心得
经过三个月的生产环境运行,这套方案表现出几个显著优势:
- 性能稳定:MoE架构的Qwen3.5在DGX Spark上平均响应时间<500ms
- 易于扩展:新增节点只需10分钟配置时间
- 管理便捷:团队自助申请Key,财务按用量结算
- 成本可控:相比云服务节省约60%成本
一个特别实用的技巧是设置mem-fraction-static=0.80,这能确保KV Cache有足够内存,避免因内存不足导致的性能波动。我们在压力测试中发现,当该值低于0.75时,长上下文(>128k)场景的性能会下降约15%。
