@lucky-001 先搞清楚本地你能够生产什么,一般情况下做视频3090是够了的,你要是能够有收益的话那么你可以上5090,如果你只是玩玩,现在的价格真没必要
随心录
-
双显卡叠加 VRAM 玩本地模型的迷思,两年过来人血泪谈,最终直上32gb 单卡 -
5090D+Qwen3.8-27B-NVFP4+ SGLang+ WSL 部署方案文档Qwen3.8-27B SGLang 推理服务 · WSL 部署方案文档
项目:darksidewalker/qwen3.8-27b-sglang-dspark-blackwell内容:NVFP4 量化版 Qwen3.8-27B + DSpark 投机解码 drafter,单张 RTX 5090(32GB)高吞吐推理整理日期:2026-08-22(基于实际部署过程复盘)
一、项目概述
项 说明 ---------------------------以下由AI整理 模型 Qwen3.8-27B,NVFP4 权重 + NVFP4 lm_head + FP8 KV cache 加速 DSpark drafter 投机解码(草稿块整体验证),实测峰值 ~300 tok/s 级 引擎 SGLang 官方预构建镜像 lmsysorg/sglang:qwen38-27b(免 JIT 编译)显存占用 godspeed 约 31 GB / 32 GB;vision 约 30 GB 上下文 godspeed(纯文本)237,568 tok;vision 150,000 tok,wsl环境上下文设置200K,DeepSeek-herness调用正常,速度非常快 服务端口 API 8040 · Caddy 网关 8041 · Grafana 8042 · Prometheus 127.0.0.1:9091 模型 ID qwen3.8-27b-nvfp4(--served-model-name固定,OpenAI 兼容接口)
硬件 / 系统要求
- Linux x86_64(本方案为 WSL2 Ubuntu 22.04)
- NVIDIA RTX 5090 / 5090D(Blackwell sm_120),驱动 ≥ 580(本机 610.43.02,CUDA UMD 13.3)
- 磁盘:镜像约 41 GB + 权重约 20 GB
本机实际环境
WSL2 内核 6.18.33.2-microsoft-standard-WSL2 · Ubuntu 22.04 (jammy) GPU: NVIDIA GeForce RTX 5090 D 32GB CPU:9850X3D【游戏佬】 内存:DDR5 48G WSL划分38G docker-ce 29.7.2 + containerd 2.3.3(systemd 服务,enabled 自启) nvidia-container-toolkit 1.20.0(daemon.json 已注册 nvidia runtime) docker daemon 走代理 127.0.0.1:10809(http-proxy.conf drop-in)
二、部署流程(WSL 适用)
步骤 0 · 前置检查
nvidia-smi # 确认驱动 ≥ 580、GPU 可见 docker info | grep -i nvidia # 确认 nvidia runtime 已注册 docker ps # 确认 CLI 与守护进程通信正常步骤 1 · 克隆项目
cd ~ git clone https://github.com/darksidewalker/qwen3.8-27b-sglang-dspark-blackwell.git sglang cd ~/sglang cp .env.example .env # 默认值即可跑通,按需修改步骤 2 · 脚本 Docker 化改造(关键步骤,见第四章)
原项目面向 Podman 编写,在 Docker 环境必须先改 4 个脚本:
setup.sh、run-sglang-godspeed.sh、run-sglang-vision.sh、monitor.sh步骤 3 · 拉取镜像 + 准备权重
docker pull lmsysorg/sglang:qwen38-27b # ~41 GB,走国内镜像加速 ./setup.sh # 或手动下载权重到 ./models/权重目录结构(本机实际布局,主模型 18G + drafter 1.4G):
~/sglang/models/ ├── Qwen3.8-27B-NVFP4-RTX5090-LMHead4/ # 主模型(target) └── Qwen3.8-27B-DSpark-NVFP4/ # DSpark drafter大文件建议手动下载后放入对应目录(HuggingFace 后台直连下载易中断留半截文件)。
步骤 4 · 启动与验证
./run-sglang-godspeed.sh start # 纯文本模式(最快) ./run-sglang-godspeed.sh status # 反复执行直到 "HTTP 200 (ready)",首次加载约 1-2 分钟验证三连:
# 1. 模型列表 curl -s http://localhost:8040/v1/models # 2. 实际推理(含思维链) curl -s http://localhost:8040/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{"model":"qwen3.8-27b-nvfp4","messages":[{"role":"user","content":"你好"}],"max_tokens":100}' # 3. GPU 占用(应接近 30.8/32.6 GB) nvidia-smi实测结果:推理正常返回且带
reasoning_content思维链字段;GPU 30822/32607 MiB。步骤 5 · (可选)监控仪表盘
./monitor.sh up # Grafana 8042 / Prometheus 9091 / Caddy 8041 ./monitor.sh dashboard # 打印面板地址和登录提示 ./monitor.sh status # sglang target 仅在推理服务运行时为 UP,属正常
三、部署过程中遇到的问题
问题 1 ★核心故障 · docker 命令全部卡死
现象:任何
docker xxx命令无限挂起(docker ps卡死无输出)。根因:
/usr/bin/docker曾被替换为一个「podman 语法翻译」包装脚本——它把参数里的--device nvidia.com/gpu=all改写为--gpus all,最后执行exec docker "${args[@]}"。但 PATH 解析时docker找到的就是它自己 → 无限 exec 递归,永不返回。诊断方法:
file /usr/bin/docker # 输出 "Bourne-Again shell script" = 异常 # 正常应为 "ELF 64-bit LSB pie executable"正确修复(从本地 apt 缓存解出真二进制覆盖,无需联网):
# 1. 确认已安装版本 dpkg -l docker-ce-cli # 例: 5:29.7.2-1~ubuntu.22.04~jammy # 2. 版本必须与守护进程一致,从缓存 deb 解出 dpkg -x /var/cache/apt/archives/docker-ce-cli_<版本串>.deb /tmp/x file /tmp/x/usr/bin/docker | grep ELF # 先验明正身再覆盖 # 3. 覆盖回去 sudo cp /tmp/x/usr/bin/docker /usr/bin/docker sudo chown root:root /usr/bin/docker && sudo chmod 755 /usr/bin/docker教训:给
/usr/bin/下的真实二进制做同名包装脚本时,包装器内部绝不能再以裸命令名调用自身。问题 2 · 修复放错位置,重启后复发
现象:第一次修复把真二进制解压到
/tmp/docker-extract/,再用 PATH 前缀的 shim 指过去。当时能用,WSL 重启后全部失效。根因:Ubuntu 每次 WSL 启动会自动清空
/tmp(tmpfiles 清理机制)。放在 /tmp 的二进制没了,shim 变成死链;同时裸docker又命中 /usr/bin 下的递归包装脚本 → 故障复现。教训:持久化修复必须落在系统盘常规路径(如
/usr/bin/);/tmp只能放临时产物。问题 3 · WSL 重启后服务消失(非故障)
现象:WSL 重启后 API 8040 无响应,容器状态
Exited (0)。说明:这是正常行为。WSL 关闭时 systemd 有序终止 dockerd 与容器(退出码 0 = 干净退出),显存随之释放。dockerd 是 enabled 服务会自启,但业务容器需要手动拉起:
cd ~/sglang && ./run-sglang-godspeed.sh start关闭 WSL 时不需要单独停 docker 或容器,Windows 侧直接关即可。
问题 4 · 双目录混淆
现象:
~/sglang(原版克隆)与~/sglang-qwen(改过的副本)并存,在旧目录里启动报podman: command not found。处置:修好的脚本 +
.env全部迁回~/sglang(权重实体本来就在它的 models/ 下),删除冗余的~/sglang-qwen。现在全系统只有一个入口~/sglang。教训:克隆副本要及时合并回主目录或明确改名区分,避免「改了 A 跑了 B」。
问题 5 · 无免密 sudo 的自动化障碍
现象:WSL 用户未配置 NOPASSWD,脚本化提权受阻。
处置:密码存于
~/.hermes/.env(SUDO_PASSWORD 变量),配合 askpass 脚本:set -a; source ~/.hermes/.env; set +a export SUDO_ASKPASS=$HOME/.hermes/sudo-askpass.sh # 脚本内容: printf "%s" "$SUDO_PASSWORD" sudo -A <命令>
四、原作者的非标准 Docker 问题及修复方案
4.1 原作者的方案是什么
原作者环境不用 Docker,而是 rootless Podman 技术栈:
维度 原作者(Podman) 说明 容器引擎 Podman(rootless 无守护进程) 非 Docker GPU 透传 --device nvidia.com/gpu=all依赖 NVIDIA CDI 规范 编排 podman-compose 非 docker compose README 明确写了:"Equivalent Docker + nvidia-container-toolkit also works; the scriptscall
podman, add a shim if you use Docker." —— 即官方认可 Docker 等效可行,但所有脚本硬编码调用podman,Docker 用户要么加 shim 要么改脚本。4.2 为什么在本机不能直接用 Podman 方案
- 本机已装好完整 Docker CE 29.7.2 + nvidia-container-toolkit,daemon.json 已注册 nvidia runtime,再引入 Podman 属于重复建设;
- WSL2 下 rootless Podman 配置链路更长(uidmap/subuid/CDI 注册),维护成本高于现成 Docker。
4.3 修复方案:脚本 Docker 化(采用的方案)
对 4 个脚本做系统性替换:
原写法(Podman) 改为(Docker) 出现位置 podman pull/podman image inspectdocker pull/docker image inspectsetup.sh, run-*.sh podman run -d ...docker run -d ...run-*.sh --device nvidia.com/gpu=all--gpus allrun-*.sh(GPU 透传的关键差异) podman rm -f/podman ps/podman logsdocker rm -f/docker ps/docker logsrun-*.sh podman network create/inspectdocker network create/inspectrun-*.sh(监控网络互通) podman-compose -f docker-compose.yml up -ddocker compose -f docker-compose.yml up -dmonitor.sh GPU 透传差异的本质:
- Podman/CDI 把 GPU 当作「设备」挂载,语法是
--device nvidia.com/gpu=all; - Docker 用 nvidia-container-toolkit 的专用参数
--gpus all(等价效果,底层同样走 libnvidia-container); - 两者的 daemon.json 侧配置不同(CDI 注册 vs nvidia runtime 注册),不可混用语法。
4.4 备选方案:shim 适配层(曾用过,已弃)
即保持脚本不动,在 PATH 前置一个
podman命令 shim 转发给 docker 并翻译参数。本项目早期还额外写过反向 shim(把脚本的--device语法翻译成--gpus)。弃用原因:
- shim 若依赖 /tmp 存放真二进制,WSL 重启即碎(见问题 2);
- 参数翻译层是额外的出错面(本项目就因翻译层递归把自己卡死,见问题 1);
- 直接改脚本是一次性的、可审计的 diff,长期维护成本最低。
结论:一次性项目优先直接改脚本;只有脚本不可改动(如只读镜像内)才考虑 shim。
五、日常运维速查
服务管理
cd ~/sglang ./run-sglang-godspeed.sh start # 启动(纯文本,最快) ./run-sglang-godspeed.sh status # 状态 + 就绪检查 ./run-sglang-godspeed.sh logs # 跟踪日志 ./run-sglang-godspeed.sh stop # 停止 ./run-sglang-vision.sh start # 切视觉模式(同一 GPU 二选一,先 stop 再 start)API 调用
curl -s http://localhost:8040/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{"model":"qwen3.8-27b-nvfp4","messages":[{"role":"user","content":"你好"}]}'思维链控制(
.env中DEFAULT_CHAT_TEMPLATE_KWARGS,默认 medium):{"reasoning_effort": "low"} // 更快更省 {"reasoning_effort": "xhigh"} // 更深思考 {"enable_thinking": false} // 完全关闭思维链也可单请求覆盖不重启:请求体加
"chat_template_kwargs":{"reasoning_effort":"xhigh"}。常用 .env 参数
参数 默认 说明 HOST_PORT 8040 对外 API 端口 SERVED_MODEL_NAME qwen3.8-27b-nvfp4 /v1/models 暴露的 ID CONTAINER_NAME sglang-qwen38 容器名 SGGLANG_IMAGE lmsysorg/sglang:qwen38-27b 镜像 DEFAULT_CHAT_TEMPLATE_KWARGS {"reasoning_effort":"medium"} 思维链开关 故障速查表
症状 排查方向 docker 命令卡死 file /usr/bin/docker应为 ELF;若为 script 按第三章问题 1 修复启动报 podman: command not found在错误目录跑了旧脚本,确认 cd ~/sglangstatus 一直 503 首次加载权重需 1-2 分钟,看 logs;显存不足时先释放 GPUvision 启动 OOM 降 --mem-fraction-static至 0.80、上下文至 ~120k(README 建议)Prometheus target DOWN 未启动推理服务时属正常,服务 ready 后自动恢复 WSL 重启后 API 不通 容器随 WSL 停止,手动 start即可(正常现象)
六、附录 · 关键文件清单
~/sglang/ ├── .env # 本机生效配置(含端口/镜像/模型仓库名) ├── .env.example # 配置模板 ├── setup.sh # 拉镜像+下载权重(已 Docker 化) ├── run-sglang-godspeed.sh # 纯文本预设 start|stop|logs|status(已 Docker 化) ├── run-sglang-vision.sh # 视觉预设(已 Docker 化) ├── monitor.sh # 监控栈管理(已 Docker 化,docker compose) ├── docker-compose.yml # caddy/prometheus/grafana/dcgm 四件套 ├── make_dashboard.py # Grafana 面板生成器 └── models/ # 权重实体(18G 主模型 + 1.4G drafter) ├── Qwen3.8-27B-NVFP4-RTX5090-LMHead4/ └── Qwen3.8-27B-DSpark-NVFP4/ /usr/bin/docker # 真 CLI 二进制 v29.7.2(勿用脚本覆盖!) /etc/docker/daemon.json # registry-mirrors + nvidia runtime /etc/systemd/system/docker.service.d/http-proxy.conf # daemon 代理 127.0.0.1:10809