三个月前,我从柜子里翻出两张吃灰的2080Ti,做了个在旁人看来有点离谱的决定:让这两张老卡组双卡,一起跑27B参数的大模型。当时身边搞AI的朋友都劝我别折腾,理由是27B模型光权重就要占15GB上下,加上KV Cache和临时计算缓冲,单卡11G肯定爆,双卡22G也只是“看起来够”。但三个月跑下来,我的结论很明确:双卡2080Ti跑27B不但可行,而且是一套性价比极高的低显存本地部署方案。这篇“老显卡实验室”系列的下篇,我不聊空泛的理论,只讲实操,核心围绕三块:双卡显存账本怎么记、去审查模型怎么选、选型口诀怎么用。
这篇文章适合三类人:一是显卡预算有限、但手里正好有老卡的朋友;二是对数据隐私敏感、想把大模型完全跑在本地的人;三是喜欢玩各种模型、对去审查版本有好奇心的玩家。看完你会清楚两张11G老卡到底能装下多大的模型,也真正明白量化、上下文、批处理之间是怎么互相抢显存的。
1. 双卡2080Ti显存账本:算清27B的真实占用
1.1 为什么是双卡2080Ti?从单卡11G到双卡22G的硬件底账
先快速回顾2080Ti为什么值得折腾。这张卡是2018年的旗舰,11GB GDDR6显存,带宽616GB/s,放在今天跑大模型推理,单卡显得很局促,但它的二手价格已经掉到很亲民的位置,而且两张卡通过NVLink或PCIe通道做双卡,能获得22GB总显存。22GB这个数字,正好卡在“能跑20B以上模型”的门槛上,属于一个很微妙的甜点区。
很多人问,为什么不用3090、4090?因为贵。低显存方案的核心思路是“老卡数量换显存”,两张2080Ti的总成本通常只有一张3090的五分之一到三分之一,但推理性能在纯生成场景下并不差太多。代价是什么?是显存带宽的瓶颈,以及双卡之间数据交换的开销。这个账必须算清楚:你买的不是性能,是“显存容量+够用的带宽”,换来的是“本地能跑更大模型”这个核心能力。
我实测的环境供参考:X99平台,双路2080Ti 11G,板载PCIe 3.0 x16槽位两条,系统内存64GB,系统盘是普通SATA SSD。这套配置在二手市场非常平民化,但它跑27B模型的实战效果,比很多云GPU实例要稳。
1.2 模型加载时的显存“背账”:权重、KV Cache与计算缓冲
显存账本不是“模型文件多大就拿多少显存”这么简单。一次完整的27B模型推理,显存占用由三块组成:参数权重、KV Cache、推理缓冲区。
参数权重是最大的固定开销。一个27B模型,如果按FP16存储,理论上需要54GB,显然两张2080Ti根本放不下。所以必须量化,这是低显存跑大模型的第一前提。以最常见的4bit量化(Q4_K_M)为例,27B模型的权重大约压缩到16GB左右,刚好能塞进22GB的显存里。这还没算其他开销,所以你会看到很多人说“理论上能装,实际跑起来会爆”,原因就在这里。
KV Cache是第二个大开销,它随上下文长度和并发批处理规模线性增长。以GQA模型为例,27B模型在8K上下文、单线程推理时,KV Cache大约占用1.5GB到3GB,具体取决于层数、注意力头数和量化方式。如果开长上下文到32K,这个数字会飙升到6GB以上,直接把显存顶穿。第三个是计算缓冲,包括临时激活值和CUDA context本身,通常预留1GB到2GB比较保险。
我自己记账时有条公式:可用显存 = 量化后权重 + KV Cache + 1.5GB缓冲。22GB的总显存,跑Q4_K_M量化27B模型,权重约16GB,留给KV Cache和缓冲的空间只有6GB,所以上下文长度不得不控制在8K到16K之间。想跑更长上下文,只能换更激进的量化,或者牺牲一部分批处理能力。
1.3 双卡通信总线和PCIe带宽如何影响账面
双卡跑模型的通信开销,经常被新手的显存账本漏掉。2080Ti支持NVLink,但NVLink的带宽和可用性在不同驱动、不同主板上差别很大;更多时候我是用PCIe 3.0 x16通道直连,理论带宽大约16GB/s(双向),实际用起来能到10GB/s左右就算不错。
这意味着什么?如果你用张量并行(Tensor Parallelism)方案,每一层计算前要把中间结果拆给两张卡,再在每层之间同步,这部分数据交换非常频繁。在27B模型上,我实测用llama.cpp的拆层方案(每张卡放不同层)比张量并行更稳定,因为拆层只需要在层边界同步一次,通信开销远小于每层都同步的张量并行。
但拆层方案也有它的代价:两卡负载天然不均衡,第一张卡要处理输入嵌入层、大量前几层计算,第二张卡相对清闲。实测下来,第一张卡的显存占用往往比第二张多1GB到2GB,所以分配层数时不能简单对半分,得手动调。
2. 27B模型选型:从通用到去审查模型,怎么挑怎么配
2.1 27B到底是个什么体量:比7B强在哪,比70B省在哪
27B是当下本地部署的甜点参数规模。21B到27B这个区间,模型已经有足够的推理能力,能处理复杂指令、长上下文对话、代码生成、结构化输出,而它的量化体积又比70B小很多。一张22GB显存的双卡系统,恰好能装下27B的4bit量化版本,这属于“勉强够、但够得很舒服”的边界。
我用27B模型和之前跑过的7B、13B模型对比,最直观的差异是:指令遵循能力明显提升。7B模型经常答非所问,13B偶尔会逻辑混乱,27B则能稳定按你给的格式输出,写代码也能考虑更多边界条件。它不是那种“我为了跑它而委屈适配”的模型,而是真正能当生产力工具的。
这背后的原因是参数量带来的知识密度和推理深度提高。27B模型在常识、推理、代码、多语言任务上的表现,已经接近甚至超过一些老的闭源大模型。对于普通用户和中小团队来说,这是本地部署的“甜点区间”:比7B、13B聪明得多,又比70B、百B级模型省显存,不需要四卡八卡那种服务器配置。
2.2 去审查模型是怎么回事:本地玩家的“定制午餐”
所谓去审查模型,英文社区一般叫uncensored model,指的是在微调阶段去掉了原本模型内置的拒绝机制、道德审查和风格限制,让模型更“直白”。这类模型在本地玩家圈里相当流行,原因很实际:审查机制会大幅增加模型的“废话率”,经常强迫模型拒绝回答一些明明很中性的问题。去审查模型则尽量只保留世界知识和指令执行能力,不预设太多价值观判断。
我用过的去审查模型,主要有两类来源:一是社区基于Qwen、Llama、Mistral等开源模型做LoRA微调的产物;二是用DPO等方法专门训练过的“诚实”版本。它们的共同点是回答更直接、更少“作为AI,我无法……”这类套话。这对写代码、做技术问答、处理敏感技术话题时有明显优势。
但必须提醒一句:去审查不等于“更聪明”。很多去审查模型在去审查的同时,也会损失一部分通用能力和指令跟随精度,因为它们通常用更小的数据集做微调。所以选模型时要看具体分支的评价,不能只看“去审查”的标签就闭眼下载。
我自己的选型逻辑是:先看基础模型的生态,再看去审查微调的质量。以Qwen系列为例,Qwen2.5-27B的社区生态非常丰富,各种量化版本、微调版本一应俱全,我也用过它做底座的去审查分支,整体效果稳定。Llama系和Mistral系也有对应版本,不过27B这个规模在线分支相对少一些。
2.3 量化版本和格式选择:GGUF、GPTQ、AWQ怎么选
量化方式决定了模型体积、推理速度和输出质量。当前最主流的三条路线:GGUF、GPTQ、AWQ。对双卡2080Ti这种环境来说,我的优先级排序是GGUF > GPTQ > AWQ。
GGUF是llama.cpp系的原生格式,支持灵活的分层加载、CPU+GPU混合推理,还能把模型切分到多张卡上,是我日常使用最多的格式。27B模型的GGUF量化版本,Q4_K_M大约16GB,Q5_K_M约18GB,Q6_K约21GB。22GB显存下,Q4_K_M是甜点,Q5_K_M偏紧但也能跑,Q6_K基本上只能很勉强,需要把更多层放到CPU。
GPTQ是类似ExLlama、AutoGPTQ这类推理框架使用的格式,针对GPU推理做了优化,速度不错,但它不太支持GPU+CPU混合卸载,显存不够时就很难受。AWQ同理,主打硬件友好的权重缩放,但生态相对封闭。
我提供一个选型参考表,是基于我这三个月的实测数据:
| 量化级别 | 27B权重大小 | 22GB双卡可跑性 | 推荐上下文 | 输出质量 |
|---|---|---|---|---|
| Q4_K_M | 约16GB | 很轻松 | 8K-16K | 良好 |
| Q5_K_M | 约18GB | 偏紧,需调层 | 4K-8K | 优秀 |
| Q6_K | 约21GB | 很勉强,配CPU卸载 | 2K-4K | 优秀 |
| Q8_0 | 约28GB | 不可跑 | - | 接近无损 |
选型口诀很简单:先保证装得下,再追求质量。跑不起来的Q8,远不如稳定输出的Q4。对27B模型,Q4_K_M到Q5_K_M之间的量化档位,从输出质量上看差别没有想象中大,但显存占用差距却非常明显。
3. 实操要点:双卡推理的部署与调优
3.1 llama.cpp与双卡分载:最稳的低显存方案
llama.cpp是目前低显存跑大模型最成熟的工具链,支持把模型按层拆分到多张GPU。核心命令是--n-gpu-layers,它决定模型有多少层加载到GPU,剩下的层留在CPU。双卡场景下,llama.cpp会根据GPU显存自动分配层数到两张卡上,但实际分配效果取决于驱动的显存探测机制。
我的做法是先指定总GPU层数,再手动调整。比如27B模型共56层,双卡总显存22GB,我会先把后面48层放到GPU,前面8层留给CPU,因为输入嵌入层和底部的层计算开销相对小,放到CPU影响没那么大。然后启动时观察显存占用,如果第一张卡显存还有富余,就把CPU层数减少,多放几层进GPU。
实际命令类似:
llama-server -m /models/Qwen2.5-27B-Q4_K_M.gguf \ --n-gpu-layers 48 \ --ctx-size 8192 \ --host 0.0.0.0 --port 8080注意llama.cpp会自动把GPU层拆分到两张卡上,但有时候分配不均,一张卡快满了另一张卡还空着。这时候可以在启动参数里加--split-mode layer并配合--main-gpu指定主卡,再通过--tensor-split手动调整两张卡的负载比例。这个参数我调了很久才明白,它接受逗号分隔的比例,比如--tensor-split 6,5表示第一张卡承担6份负载、第二张承担5份。
3.2 显存不够时的CPU卸载策略
双卡22GB听上去挺大,但一旦你把上下文拉长、或者用Q5以上的量化,显存就又不够了。这时候的应对策略是“CPU卸载”。llama.cpp允许部分层在CPU上算,只要你有足够大的系统内存。
系统内存至少要有32GB,推荐64GB。我在做CPU卸载时,会刻意把注意力层尽量留给GPU,因为注意力层计算密集,放CPU会严重拖慢速度;而FFN层和低层嵌入放CPU,性能损失相对可接受。这属于一个很实用的调优技巧:不是所有层都“地位平等”。
实测数据供参考:56层的27B模型,48层放GPU、8层放CPU时,生成速度大约每秒8到10 token;40层放GPU、16层放CPU时,速度掉到每秒4到5 token。所以除非实在装不下,CPU层数尽量控制在10层以内。
3.3 上下文长度与KV Cache的平衡:8K还是32K
KV Cache是双卡跑27B模型最容易踩的坑。很多人以为模型支持32K上下文,我就直接开32K,结果刚启动就OOM。原因很简单:KV Cache大小和上下文长度成正比,32K上下文比8K要多占4倍显存。我上面算过,27B模型在Q4_K_M下,16K上下文的KV Cache大约3GB到4GB,22GB显存扣除权重16GB后,所剩无几。
正确的做法是先用小上下文把模型跑通,再逐步加大。我会用--ctx-size 4096起步,确认稳定后加到8192,再到16384。每次都观察显存占用和生成速度,找到一个“不OOM、速度可接受”的边界值。我自己的经验是,Q4_K_M量化的27B模型,在双卡2080Ti上跑12K到16K上下文是甜点区,再往上就只能靠CPU卸载硬撑了。
另外还有个容易被忽略的点:--batch-size参数。这个值影响推理时的批量处理规模,对显存占用也有影响。默认值通常是512,如果显存紧张,可以降到256甚至128,虽然吞吐略有下降,但能腾出不少临时显存。
3.4 推理服务化:接入OpenAI兼容API
部署模型不光是为了自己在终端里敲命令,很多时候还要接进应用。llama.cpp的llama-server自带OpenAI兼容API,直接启动后可以用HTTP请求调用。这样本地模型就能兼容市面上绝大多数AI应用,比如各种聊天前端、知识库工具、自动化脚本。
启动后,默认地址是http://localhost:8080/v1,可以用curl快速测试:
curl http://localhost:8080/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{"model":"qwen","messages":[{"role":"user","content":"你好,介绍一下你自己"}]}'返回的JSON结构和OpenAI完全一致,接入门槛为零。我用这种方式把它接到了自己写的一个自动化脚本里,用来批量处理文本分类和关键字提取,效果很稳定。
4. 实跑中的常见问题与排查
4.1 OOM显存不足:不是模型太大,是你没算账
双卡跑27B最常见的错误就是OOM,也就是显存溢出。除开真的下错量化版本的情况,大多数OOM都是KV Cache设置太大或批处理参数没调好导致的。
遇到OOM,我的排查顺序是:先看nvidia-smi确认两张卡的显存占用,再看是启动阶段就爆还是运行一段时间后爆。启动阶段就爆,通常是权重+固定缓冲就超过了22GB,这时要考虑换更低量化,或增加CPU卸载层数。运行一段时间后才爆,大概率是KV Cache随上下文增长撑爆了显存,这时要缩短--ctx-size或降低--batch-size。
还有个很多人忽略的坑:llama.cpp在启动时会预分配一部分CUDA context显存,这部分不是实际模型大小,但经常占掉1GB到2GB。所以算账时一定要把“系统开销”这个隐藏项算进去。
4.2 生成速度慢:双卡不是双倍性能
双卡跑模型的生成速度,并不等于单卡的两倍。我用Q4_K_M量化27B模型实测,单卡跑到每秒7到9 token,双卡也差不多是这个范围,甚至在某些层分配不当的时候会更慢。原因很简单:模型层是串行依赖的,拆层后数据要在一张卡算完再传给另一张卡,通信开销抵消了并行收益。
所以对“速度党”来说,双卡的意义是“能跑更大模型”,而不是“跑得更快”。如果你的目标是追求速度,那应该单卡跑更小的模型,比如13B或7B,速度会快得多。
如果确实想提升双卡速度,重点调--tensor-split,让两卡的负载尽量均衡。其次是降低上下文长度,因为长上下文会增加每步的计算量,拖慢生成。最后就是确保两卡都插在PCIe 3.0 x16槽位上,不要用x8或x4,否则通信带宽会进一步拖累。
4.3 输出质量不稳定:量化档位和采样参数都有影响
有朋友跟我反馈,说同一个模型量化到Q4后“变笨了”。这个现象真实存在,但很多时候不是量化的问题,而是采样参数没调好。Q4_K_M在大多数任务上和Q8的差距在可接受范围内,如果你感觉输出“明显变傻”,先检查temperature、top_p、repeat_penalty这几个参数。
我自己的常用配置是temperature 0.7、top_p 0.9、repeat_penalty 1.1。写代码任务我甚至会降到temperature 0.3,减少随机性。相比一味追求高量化档位,把采样参数调对,对输出质量的提升更直接。
另外,去审查模型的采样参数要格外注意,因为去审查模型往往对指令的“忠实度”更敏感,温度太高容易发散,temperature超过1.0基本就进入“胡言乱语”状态了。
4.4 双卡通信异常:驱动、NVLink与PCIe的坑
双卡部署中还有一个非常隐蔽的问题:两张卡的通信不稳定。表现是生成到一半突然卡死,或者输出内容开始乱码。排查时先看nvidia-smi里两张卡是否都在正常状态,再用nvidia-smi topo -m查看两卡之间的拓扑连接。
我遇到过一种情况:两卡插在同一个PCIe交换机下面,带宽被共享,跑起来一卡一卡。后来换了插槽,让两卡各走各的PCIe根端口,通信才顺畅。另外,如果主板支持NVLink,优先用NVLink桥接,它会比PCIe通信快很多,不过2080Ti的NVLink桥接器现在已经不好买了,没有的话也不影响跑,只是速度差一些。
5. 选型口诀与最终心得
5.1 老显卡选型口诀:显存账本、量化档位、模型生态
这三个月的实操经验,我给自己总结了一套选型口诀,分享出来:
先算显存账本,再谈模型大小。权重、KV Cache、缓冲三项加起来,必须低于总显存,否则一切白搭。能上Q4不上Q8,能跑起来才算数。量化质量差异远小于“跑不起来”的差异。优先生态好的基础模型。不管是不是去审查版本,先看它基于哪个模型,Qwen、Llama、Mistral这几个生态最成熟,各种量化版本和微调版本都齐全,出问题也容易找到社区经验。去审查版本认准社区口碑。不是所有去审查模型都值得装,看下载量、看评测、看更新频率。
对于手上正好有2080Ti的朋友,我的建议是直接上双卡。单卡11G只能跑7B到13B模型,性能上限明显;双卡22G能跑到27B到33B模型,量级完全不同。两卡的成本很低,但能玩的模型范围大了一倍不止。如果你现在正在纠结是买新卡还是用老卡组双卡,我的结论是:先看看手头的电源和主板插槽够不够,够的话,双卡2080Ti是低显存方案里最值得尝试的路线之一。
5.2 三个月摸出来的几条小技巧
最后放几条可能帮到你的私人经验。
一是模型文件不要放在机械硬盘里跑。27B模型Q4量化文件大约16GB,从机械硬盘加载一次要一分钟以上,换成SATA SSD大概十几秒,如果是NVMe SSD基本秒开。这个体验差距极大,强烈建议把模型放到SSD上。
二是双卡跑模型时,别开太多后台程序。浏览器、视频播放这些会占用显存和PCIe带宽的东西,都关掉。别小看这个,我试过挂着浏览器看视频,模型生成速度直接掉20%。
三是定期清CUDA缓存。运行时间长了,显存里会有碎片化的CUDA缓存,导致可用显存变小。重启一次推理服务,通常就能释放干净。
四是用双卡跑27B模型时,不要迷信“越大越好”。有些33B、32B模型虽然参数比27B多,但可能因为微调质量不好或者量化损失更大,实际表现反而不如成熟的27B分支。选模型时,社区下载量和最近更新日期,是比我这种个人经验更靠谱的指标。
五是最重要的:这个组合的可玩性比想象中高。我从最初跑Qwen的27B基座,到后来尝试各种去审查分支,再到接API做自动化,三个月下来,这套双卡2080Ti机器已经成为我日常工作和写作中离不开的工具。它不是最快的,不是最省电的,但它让我在预算有限的情况下,真正体验到了本地大模型的能力。如果你手里正好也有两张老卡,别再让它们吃灰了,值得折腾一次。