NVIDIA 上跑本地大模型:一张 3090 Ti 跑 27B 免审模型(附下载地址与实测对照)

NVIDIA 上跑本地大模型:一张 3090 Ti 跑 27B 免审模型(附下载地址与实测对照)


一张 3090 Ti 跑 27B 免审模型:改写/翻译类比原双卡快 2.2 倍,日常对话快 32%。代价是量化从 8 位降到 4 位,且质量尚未验证。

上一篇讲的是 Mac(Apple 芯片)。这篇讲英伟达。

同样一句话先给结论:

一张 24G 的 3090 Ti 跑 27B 免审模型:改写/翻译类任务比原来的双卡方案快 2.2 倍,日常对话快 32%。 代价是量化从 8 位降到 4 位 —— 值不值,第六节算了细账。

而且——另一张卡完全空着,还能同时跑图像生成。


一、为什么?先看一个比喻

大模型像一本书。正文可以压缩(这就是"量化"),压得越狠,占地方越小、读得越快,但会损失一点点理解力。

常见的压缩档位:

档位好比27B 模型占多大
原始精度(BF16)精装大开本约 55 GB
FP8(8 位)普通平装约 29 GB
int4(4 位)口袋本约 15 GB

关键在这里:29 GB 装不进一张 24 GB 的卡,所以必须两张卡分摊(叫 TP=2)——卡之间来回传数据,本身就慢。而 15 GB 塞进一张卡绰绰有余,另一张卡空出来能干别的。

所以"用 4 位"不是省钱的将就,而是让单卡跑得动的必要条件。

二、这次用的免审模型(含地址)

HuggingFace 上叫 Qwen3.8-27B 的 4 位模型有十几个,我挑的这个是唯一一个装完就能跑的:

https://huggingface.co/Ar4ikov/Qwen3.8-27B-Uncensored-AWQ-W4A16-ASYM-HyperQwen

体积 16.9 GB。选它的三个理由:

  1. 零预处理 —— 别的包下回来还得自己跑几个脚本把词表头转成 8 位、再生成一份"小抄词表",得几十分钟还可能出错。这个包作者已经做完了。
  2. 自带投机解码所需的部件(MTP 头 + 40,960 词的草稿词表)—— 这是它比同类快的原因,也是别的包缺的东西。
  3. 免审血统和你 Mac 上那个一致 —— Mac 上跑的 orcarouter/Qwen3.8-27B-Uncensored,这个包就是从同一份权重转过来的。两台机器"性格"一致,不会出现"换了台机器像换了个人"。

这个模型是 4 位混合精度,不是全都压成 4 位:

部分精度
主体线性层(411 个模块)4 位(非对称 AWQ,group 128)
输出词表头 / 输入词表 / 投机头 / 草稿词表8 位
视觉塔 / 部分门控投影 / 归一化层保持 16 位不动

所以它其实是"哪儿该压、哪儿不能压"分开处理的,这也解释了为什么它比粗暴全压成 4 位的好用。

三、引擎:HyperQwen

模型只是"书",还得有"读书的人"(推理引擎)。这次用的引擎:

https://github.com/syv-ai/HyperQwen          ← 引擎本体(★1652)
https://github.com/Ar4ikov/vllm-hyprfastQwen ← 上面那个模型作者的配套仓库,有现成配置

它做了什么?简单说:vLLM(主流推理引擎)+ 42 个补丁,专门为"一张 24G 卡跑 27B"调优。核心是投机解码——

打个比方:模型正常是"一个字一个字往外蹦"。投机解码是先猜 7~15 个字,再一次性验证猜得对不对。猜对了就一次性吐出来,所以快。

猜得准不准,取决于任务。这点后面实测会看到,差别非常大。

四、安装:这里有个大坑,先说

坑:这台机器上 pip 基本不可用

装引擎要下 3~4 GB 的 Python 依赖。用 pip 装?实测 0.08 MB/s,要 10 小时。

奇怪的是同一个下载地址,用 curl 测是 11.93 MB/s —— 差 140 倍。说明不是网络问题,是 pip 自己的下载模块在这条链路上有问题。

解法两条一起上:

  1. 换国内源(官方源在墙内被代理拖到 0.1 MB/s,国内镜像直连):
# 实测速度:阿里云 14.16 MB/s、中科大 2.65、腾讯 2.25、清华 1.58、官方 0.10
-i https://mirrors.aliyun.com/pypi/simple/
  1. 换装包工具,用 uv 代替 pip(Rust 写的,并行下载 + 重试强):
uv pip install --index-url https://mirrors.aliyun.com/pypi/simple/ vllm==0.29.0 ...

效果:6 分钟装完(venv 从 0 到 6.4 GB)。pip 折腾 40 分钟连三分之一都没到。

完整的安装命令

# 1. 取引擎(用上游 main,不要用作者的分支——上游已经正式收录了这个包,且新 23 个提交)
git clone https://github.com/syv-ai/HyperQwen ~/qwen-serving
cd ~/qwen-serving

# 2. 建环境(用 uv + 阿里云,见上)
python3 -m venv venv
venv/bin/uv pip install --python venv/bin/python \
  --index-url https://mirrors.aliyun.com/pypi/simple/ \
  vllm==0.29.0 huggingface_hub ninja pandas

# 3. 打补丁(42 个,必须全打)
sed -e 's/#.*//' -e 's/^[[:space:]]*//;s/[[:space:]]*$//' -e '/^$/d' patches/series |
while IFS= read -r name; do
  case "$name" in
    dflash2-backport.patch) continue ;;   # 0.28 起已是原生,跳过
  esac
  patch -p1 -d venv/lib/python3.12/site-packages/vllm < "patches/$name"
done

# 4. 下模型(用 curl,不要用 hf download,原因见第六节坑 1)
curl -L -C - --retry 5 --retry-all-errors \
  -o qwen38-uncensored-asym/model.safetensors \
  "https://huggingface.co/Ar4ikov/Qwen3.8-27B-Uncensored-AWQ-W4A16-ASYM-HyperQwen/resolve/main/model.safetensors"

# 5. 自检(官方脚本,8 项检查)
MODEL=$PWD/models/qwen38-uncensored-asym bash verify.sh --no-server
# → 期望输出末尾:verify: OK (0 failures)

五、启动:照抄作者的配置文件,不要自己拼参数

这一步我连错三次,全部记录在第六节。结论写在前面:

作者的配套仓库 Ar4ikov/vllm-hyprfastQwen 里有个 configs/ 目录,每个档位存成了一个 .env 文件,照抄即可,一个字都别改。

# 关键:先设这个,否则 FlashInfer 编译内核时报 assert cuda_home is not None
export CUDA_HOME=/usr/local/cuda-13.0     # 换成你机器上 nvcc 13.0 的位置
export PATH=$CUDA_HOME/bin:$PATH

# 单会话默认档(configs/single-dflash2.env)
MODEL=/path/to/qwen38-uncensored-asym \
SPEC=dflash2 CTX=fast PREFIX_CACHE=1 VISION=1 \
KV_MEM=4300000000 DFLASH_MAX_LEN=49152 \
bash single-user/start_qwen.sh

起来后:

curl http://localhost:18020/v1/models \
  -H "Authorization: Bearer $(cat api_key.txt)"

curl -X POST http://localhost:18020/v1/chat/completions \
  -H "Authorization: Bearer $(cat api_key.txt)" \
  -H "Content-Type: application/json" \
  -d '{"model": "qwen3.8-27b",
       "messages": [{"role": "user", "content": "你好"}],
       "chat_template_kwargs": {"enable_thinking": false}}'

⚠️ 服务默认绑 0.0.0.0 且不鉴权,一定要先生成密钥:openssl rand -hex 24 > api_key.txt

六、实测数据

硬件:2 × RTX 3090 Ti 24GB(显存带宽 1008 GB/s,功耗上限 450W) 采样参数:T 1.0 / top-p 0.95 / top-k 20(模型默认)

三个档位,速度差别很大

档位单流 C14 并发8 并发64 并发引用型
D(单会话默认)102.3240.8208.3—266.2
P(改写优化)95.9169.2173.0—315.7
B(batch 后端)48.3——1,243.6—
原来那套(双卡 FP8,8 位)77.4279.9做不到—121.3

单位 tok/s。「引用型」指要求模型逐字改写/翻译/引用给定文本的任务。

怎么读这张表

① 单流赢了,而且赢在关键处

原来开放生成是 77.4,现在是 102.3 —— 快 32%。而"引用型"从 121.3 涨到 266.2 —— 快 2.2 倍。

为什么引用型快这么多?回到那个比喻:投机解码先猜后验。当任务要求"把这段文字改写成正式风格"时,答案大量照抄原文,猜起来几乎不会错 —— 实测"平均每次验证能通过 6.26 个 token"(普通开放式写作只有 1.88)。

这正是 agent 场景的典型任务:改代码、翻译、整理文档、RAG 引用资料。

② 并发还是原来那套强

4 并发以上,原来那套(双卡分摊)反而更快(279.9 vs 240.8)。因为新方案为了换速度牺牲了请求槽位。

你要是一两个人用,这个差距吃不到。要是给多个系统提供 API,就得切 batch 档。

③ batch 档的 64 并发 = 1,243.6 tok/s

作者公布的是 1,169,我们实测反超了。但代价极大:单流掉到 48.3(从 102.3 掉一半多)。因为 batch 档把投机解码整个关了 —— 猜字省的是延迟,在大批量下反而拖累总吞吐。

一个人用不上,别开。

⚠️ 代价:量化从 8 位降到了 4 位

上面全是"赚",这一节说"花"。

原来那套是 FP8(8 位),新方案是 int4(4 位,混合精度)。虽然 4 位主体之外,词表头和视觉塔都保留在 8 位 / 16 位没动,但主体权重确实降了一档。

这笔质量损失目前还没有实测数据:

  • 官方只公布了基础版的精度(IFBench 78.3,比未量化的 79.5 低 1.2 分;困惑度 8.09)
  • 我们用这个是免审版,去审查的处理和官方测的基础版不是同一条技术路线,官方没测过
  • 我们自己也还没做质量对比(拒答探针、能力抽检都没跑)

所以现在:速度账算清了,质量账还是空的。

你的用途建议
大量改写 / 翻译 / 改代码 / 查资料问答快 2.2 倍,值得(但建议先补质量验证)
主要是聊天、写作只快 32%,要掂量 8 位换 4 位的代价
要给多个系统提供 API原来那套并发更强(279.9 对 240.8),留原来的
需要腾一张卡同时跑图像生成原来那套两张卡都占了,新方案只占一张

功耗

跑满时 GPU 吃 446W(上限 450W),利用率 100%。另一张卡 24W、完全空闲。

七、踩的坑

坑 1:hf download 已经不续传了(这个最坑)

大模型下到一半断了,重新跑同一条命令 —— 它从头开始。

我实测验证过:下到 80MB 时强杀,重跑,目录里出现两个分片:

旧的:80 MB  尾缀 51f288c6  inode 18886365   ← 原地不动,废了
新的:从 0 长到 180MB  尾缀 92caa2be  inode 18886366

同一个文件本该是同一个 inode 继续变大。

原因:huggingface_hub 从 v1.18.0(2026-06-05) 起把跨进程续传删掉了(上游 PR#4306,为修缓存损坏)。上游 issue #4196 就叫《No resuming of downloads》,至今未修。

注意别被官方文档误导:文档说"失败下载会默认续传",那指的是同一个进程内的重试,不包括"杀掉重跑命令"。

解法:改用 curl -L -C -

curl -L -C - --retry 5 --retry-delay 10 --retry-all-errors --max-time 5400 \
  -H "Authorization: Bearer $(cat ~/.hf_token)" \
  -o model.safetensors "<模型的 resolve 地址>"

HF 的下载地址实测支持断点续传(响应头有 accept-ranges: bytes)。外面套一层循环,每次先看文件大小对不对、不对就再 curl 一次。

想要 hf download 也能续传:把 huggingface_hub 钉回 1.17.0 或更低(单独建个小环境专门下载,别动引擎那个环境)。

坑 2:装完必须自检,别信"下完了"

HF 的 404 页面也会生成一个小文件,看起来"文件存在"。正确校验:

  1. 字节数精确等于官方公布的
  2. safetensors 头部能解析,且"张量数据末端"等于文件实际大小

我们下完的校验结果:

大小:16195402152 字节  ← 与官方一字不差
张量数:2388
数据末端:16195402152  ← 等于文件大小,说明没截断、没空洞

坑 3:PREFIX_CACHE=1 不能漏

这个参数让多个请求共享同一段前缀的缓存。如果你的请求都带同一段系统提示(agent 场景基本都是),漏了它每次都要重算一遍前缀。

作者的实测:64 个请求共享 5,800 token 的系统提示,不开 222 秒,开了 17 秒。

坑 4:FlashInfer 要现场编译内核

某些档位(batch 模式、CTX=long)第一次启动会现场编译一个 GPU 内核。报错长这样:

AssertionError: cuda_home is not None

或者 Ninja build failed。

解法:设好 CUDA_HOME 指向 nvcc,且 nvcc 版本必须与 CUDA 头文件的 CUDART_VERSION 完全相等(大一点小一点都不行)。

如果实在编不过(比如 batch 档的 fp8 KV 内核),batch/start_qwen.sh 里有条绕开的路:

KV=int4pth    # 改用 Triton 后端,只要 C 编译器,不要 nvcc

我们就是这样把 batch 档跑起来的(代价:上下文换成 262k、解码慢约 1.5 倍,但我们实测 64 并发仍有 1,243.6)。

坑 5:别自己拼参数(我连错三次)

第 1 次:漏传 KV_MEM → 引擎自动开池到 49,059 token
        → 15-token 验证块在 CUDA graph 捕获阶段显存不够

第 2 次:我以为"池子太大",把 KV_MEM 从 4.3e9 砍到 3.3e9
        → 报错:3.9 GiB KV cache is needed, which is larger than 3.06 GiB
        ← 方向完全反了,是太小不是太大

第 3 次:漏了 PREFIX_CACHE / DFLASH_TOKENS / INT8_ACT
        → 引用型只有 160 tok/s 而不是 315.7

正解:作者从不动 KV_MEM —— 两个档位的 KV_MEM 都是 4300000000,优化档只是把 DFLASH_MAX_LEN 从 49152 降到 36864。

照抄之后,池子读数(D 档 49,662 token、P 档 37,834 token)与作者文档逐字一致 —— 这就是配置对了的证据。

通用教训:配任何第三方项目,先去它的仓库找有没有 configs/*.env、profiles/*.env 之类的现成配置。有就照抄。只有确认没有时,才自己拼参数 —— 而且拼之前先读它的启动脚本和相关 docs/。

坑 6:别用 launchctl submit 调度"延迟重启"

这条跟模型无关,但差点把整台开发环境搞崩。

我为了"延迟重启一次服务",用 launchctl submit 建了个任务。结果 launchd 会反复重跑这个任务,而任务内容是"杀掉并重启 DSH" —— 于是变成每 15 秒自杀一次的死循环,服务永远站不稳,日志还干净得没有任何报错。

正确做法:用 nohup ... & disown,别用 launchd 调度这类一次性动作。万一建了 launchd 任务,跑完立刻 launchctl bootout。

八、速查表

你要做什么命令 / 地址
下模型curl -L -C - --retry 5 --retry-all-errors -o 目标文件 "<resolve 地址>"
装依赖uv pip install --index-url https://mirrors.aliyun.com/pypi/simple/ ...
打补丁patches/series 按行 patch -p1 -d venv/.../vllm < patches/<名字>
自检MODEL=<模型目录> bash verify.sh --no-server → 期望 OK (0 failures)
设编译环境export CUDA_HOME=<nvcc 13.0 目录>; export PATH=$CUDA_HOME/bin:$PATH
启动(单会话)SPEC=dflash2 CTX=fast PREFIX_CACHE=1 VISION=1 KV_MEM=4300000000 DFLASH_MAX_LEN=49152 bash single-user/start_qwen.sh
启动(batch)VISION=1 KV=int4pth bash batch/start_qwen.sh
关思维链请求体加 "chat_template_kwargs": {"enable_thinking": false}

关键地址

东西地址
免审模型https://huggingface.co/Ar4ikov/Qwen3.8-27B-Uncensored-AWQ-W4A16-ASYM-HyperQwen
引擎https://github.com/syv-ai/HyperQwen
作者配套(含现成配置)https://github.com/Ar4ikov/vllm-hyprfastQwen
现成配置目录上面仓库的 configs/

最后一句

Mac 那篇的结论是"稠密选小、MoE 选大";这篇的结论是"选对档位,比选对硬件更重要"。

同一个模型、同一张卡,配置对与不对,引用型任务能差 2 倍(160 vs 315.7)。而这个配置作者早就写好放在仓库里了 —— 我花了五次重启才想到去抄。

测试环境:2 × RTX 3090 Ti 24GB(1008 GB/s,450W),Ubuntu 24.04,vLLM 0.29.0 + HyperQwen 42 补丁,2026-09-23 实测。

10000举报0子龙•5天前
点击获取 ^_^
被收录:

暂无评论