查看: 5|回复: 0

显存就这么多,怎么把字吐得更快?——从 MoE、KV Cache 到 DFlash 的本地部署全景拆解

[复制链接]

21

主题

2

回帖

75

积分

注册会员

积分
75
发表于 昨天 21:33 | 显示全部楼层 |阅读模式



“一张 16GB 显卡,也能跑 27B 大模型。”
看到这句话,先别急着下载权重。
你还需要知道:用了什么量化?上下文开了多长?模型是否全部放在显存里?所谓“快”,指开始回答快,还是回答时每秒生成的 token 多?
这些条件不同,“能跑”的含义可能相差很大。模型成功加载,只是第一步;能读完你的材料、给出可靠答案,并在可接受的时间内完成,才算真正可用。
本地部署要解决的,是在输出质量满足需求的前提下,让模型装得下、上下文放得下,再让生成尽可能快。 MoE、量化、KV Cache、MTP、DFlash,分别处理这条链上的不同问题,并不是把所有开关打开,就一定能得到最优结果。
下面就从一张 16GB 显卡出发,按实际做选择的顺序,算清显存和速度两笔账。文中的具体架构以 Qwen3.8-27B 为例;16GB 配置是预算演示,不是本文已经复现的硬件实测。
一、先算总账:显存里不只有模型权重


图 1:显存总账——运行显存不只由模型权重决定,还要给上下文缓存、运行时工作区和草稿模型留位置。
一个常见误区是:下载的模型文件有 15GB,显卡有 16GB 显存,应该刚好能跑。
问题在于,模型运行还需要其他空间。除了权重,还有保存上下文的缓存、计算时的临时张量、推理引擎的工作区;如果额外挂载草稿模型来加速,还要为草稿权重和相关缓存留位置。使用图像、视频输入时,也可能增加视觉模块与中间计算的开销。
可以先记住这笔总账:
运行显存 ≈ 主模型权重 + 上下文缓存与状态 + 运行时工作区 + 可选的草稿模型及其额外开销。
这不是精确测量公式,而是一份防止漏项的预算清单。不同引擎的预分配策略、并发请求数、输入长度和运行阶段,都会改变实际占用。磁盘上的文件大小,也不等于加载后的显存占用。
所以,正确顺序不是先把最大模型塞满显存,再看能不能聊天,而是先确定任务需要多长的上下文、能接受怎样的质量和等待时间,再决定把多少空间分给权重。
下面先看通常最大的一笔:模型本身。
二、模型能不能装下:先分清参数,再看量化


图 2:一部分方块被点亮抽出(MoE 只激活部分专家),整体结构被压缩成更小更密的晶体(低比特量化)。
总参数不等于每一步参与计算的参数
“拥有 270 亿参数”和“生成一个 token 要使用多少参数”,不是同一个问题。token 是模型处理文本的单位,可以是一个字、词的一部分或其他片段,并不固定对应一个汉字。
稠密模型(Dense)没有 MoE 那样的专家选择机制:每个 token 都沿着各层的稠密计算路径前进。可以把它理解为“各部门都参与处理”。MoE 则在专家层里设置路由器,让一个 token 只调用部分专家,类似医院分诊,不需要所有科室同时会诊。具体选几个专家,由模型配置决定。
例如 30B-A3B 这类命名,通常表示总参数约 30B、每个 token 激活约 3B。它有利于降低相对于总参数规模的计算量,却不意味着权重只需要按 3B 来存。
对于希望把权重全部放入 GPU 的部署,容量要按总参数和存储精度算,不能按激活参数算。 也可以将部分专家放在系统内存中,但这会引入新的调度、计算或传输代价。因此,“MoE 省计算,不会自动按激活比例省权重空间”比“MoE 一定装不下”更准确。是否适合 16GB 显卡,要比较具体模型,而不是只看架构标签。
量化改变的是每个参数占多少空间
按 27B 参数粗算,BF16 每个参数占 2 字节,仅权重数据就约为 54GB。这里使用十进制 GB;实际文件还要看具体组件与存储格式。这显然超出了 16GB 显卡的容量。
量化用更少的比特表示权重。若理想化地把每个参数都存成 4 bit,27B 权重的原始数据约为 13.5GB;但实际量化还需要缩放因子等元数据,而且不是所有张量都用同一精度,所以不能用这个数字直接预测下载文件大小。
原始材料列出的体积梯度是:BF16 约 54GB、Q8_0 约 29GB、Q4_K_M 约 16.5GB、IQ3_XXS 约 11GB。这些可用于理解量级,但缺少对应文件与版本,不能当成所有 27B 模型的通用规格。
量化像有损压缩,但不能把 8-bit、4-bit、3-bit 简单对应成固定“画质”。低比特量化可能影响复杂推理、代码正确性、长文本稳定性等表现;影响大小取决于模型、量化方法、校准数据和任务。一个聊天时看不出明显区别的版本,不代表在你的实际工作里没有损失。
所谓“分层量化”,就是不把所有层或张量一刀切:更敏感的部分保留较高精度,其他部分压得更紧。Q4_K_M、IQ3_XXS 等是具体量化方案的名称,不是质量保证书,也不意味着每个参数恰好占 4 bit 或 3 bit。
到这里,第一个选择才算清楚:先找满足任务质量的模型与量化版本,再看它能否为缓存和运行时留下空间。 如果仍然装不下,才进入下一项取舍。
三、装不下怎么办:CPU/GPU 卸载的代价


图 3:GPU 与 CPU 两层平台之间的狭窄通道,就是跨设备传输的代价所在。
大模型由多层网络组成,“层”可以看作逐级处理信息的积木。层数是具体架构的设计结果,不能仅凭“27B”这样的参数规模推出。
如果权重无法全部进入显存,一种办法是把部分层留在系统内存,由 CPU 计算,其余交给 GPU。以 llama.cpp 为例,--n-gpu-layers 控制加载到 GPU 的层数。这类部分卸载,让“显存不够”不再必然等于“完全不能运行”。
代价是什么?首先是 CPU 侧计算与内存带宽可能成为瓶颈;其次是跨设备边界时需要传输中间数据,并进行同步。它不是简单地“每留一层在 CPU,整个模型就通过 PCIe 搬一次”,也不能一概断言只留一层就会速度断崖。具体下降多少,要看卸载比例、CPU 性能、内存带宽和引擎实现。
对交互式聊天来说,如果追求低延迟,通常应优先争取全 GPU 驻留;如果更看重模型能力,能接受多等一会儿,部分卸载也可能是合理选择。
卸载解决的是容量限制,不是免费的扩容。 一个稍小但全 GPU 运行的模型,与一个更大却依赖 CPU 的模型,哪一个更好,要由任务质量和实际等待时间共同决定。
四、上下文能开多长:KV Cache 与混合注意力



图 4:越堆越高的玻璃塔代表随上下文增长的缓存,其中少数亮起的层是全注意力层,其余是线性注意力层。
权重装下了,为什么输入一篇长文还是可能爆显存?因为模型运行时,还要保存已经读过的内容所对应的中间状态。
在标准因果全注意力中,过去 token 的 Key 和 Value 可以缓存起来,供后续生成使用,不必反复计算。这就是 KV Cache。把它比作“读书笔记”很直观,但它不是文字摘要,而是供注意力计算使用的张量;缓存放得下,也不等于模型能毫无遗漏地利用所有前文。
对于各全注意力层配置相同、K/V 维度相同的情况,原始 KV 数据量可近似写成:
         Mkv​    ≈  2×B ×T × Lfull ​ × Hkv ​× D  × s
其中,2 表示 K 和 V 两份数据;B 是批量大小,T 是缓存的 token 数,L 是全注意力层数,H 是 KV 头数,D 是每个头的维度,s 是每个元素占用的字节数。量化元数据、内存对齐和引擎预分配等,还会带来额外开销。对单个请求来说,随着输入与输出累计变长,缓存通常也会随之增大。
这解释了两种不同的优化:缓存量化减少每个元素的存储空间,混合注意力减少需要保存完整历史 KV 的层数。 前者需要后端支持,并可能影响精度或速度;后者是模型架构,不能靠部署时改一个参数随意切换。
以 Qwen3.8-27B 为例,官方配置中的文本网络有 64 层,每 4 层安排 1 层全注意力,也就是 48 层线性注意力、16 层全注意力;全注意力部分有 4 个 KV 头,头维度为 256。这些是这个模型的具体设计,不是所有 27B 模型的共同规格。模型配置
如果其他条件相同,把全注意力层从 64 层减到 16 层,这部分随序列增长的 KV 数据就降到四分之一。但线性注意力仍需要维护递归状态等数据,所以不能说整个缓存、更不能说全部运行显存,都直接变成四分之一。
还要分清两条分类轴:稠密/MoE 决定专家如何参与计算,全注意力/混合注意力决定如何处理序列信息。 稠密模型也可以采用混合注意力,不能把缓存节省笼统归功于“稠密”。
Qwen3.8-27B 的官方模型卡给出原生 262,144 token 的上下文能力。但这是模型支持的长度,不是某张显卡一定能承载的长度,更不是 262,144 个汉字;输入与输出都要计入上下文预算。模型卡
因此,选择上下文长度时,要同时过两道关:模型是否支持,以及你的剩余显存是否足够。剩下的另一道关,则是等待时间。
五、装下了为什么还慢:先分清“读输入”和“写输出”


图 5:左侧输入被一次性并行吸入(Prefill),右侧 token 光点被逐个吐出(Decode)。
一次模型请求,至少要区分两个阶段。
Prefill(预填充)是读输入。 提示词和历史对话已经确定,模型可以并行处理多个 token,建立后续生成需要的缓存。输入越长,要做的计算越多,开始回答前就可能等得越久。
Decode(解码)是写输出。 在普通自回归生成中,下一个 token 要等上一个生成后才能确定。单用户、小批量时,每步只推进少量 token,却仍需从显存读取大量模型权重。
这像从仓库搬工具到工作台加工零件:显存是仓库,权重是工具,GPU 的计算单元是工作台。 工作台放不下所有工具,需要反复搬运。预填充时,零件已经备齐,搬来一批工具可以连续加工多个零件;单用户解码时,下一个零件要根据上一个的加工结果才能确定,每轮加工一个,却仍得搬一遍所需工具。
所以,预填充能让多个 token 分摊权重搬运成本,更容易发挥 GPU 的计算能力;小批量解码分摊得少,更容易受显存带宽限制。 这不是说 GPU 总在“闲等”:高并发能提高权重复用,超长上下文也会增加注意力计算与缓存访问开销。
因此,评估“快不快”,至少要分开看首 token 延迟、生成阶段的 token/s,以及整个请求的完成时间。若框架把思考内容隐藏起来,用户看到第一段正式答案之前的等待,还可能包含一部分生成时间。
加快 Decode,不等于按相同比例缩短 Prefill,更不等于按相同比例缩短整个任务。 但对需要生成大量内容的请求,Decode 确实值得重点优化。接下来的问题是:能不能让大模型每次运行,换回不止一个最终 token?
六、一次验证多个 token:投机解码、MTP 与 DFlash


图 6:小模型整块并发“发牌”,大模型一次性验证;通过的保留,被拒绝的(红色)退回重来。
先理解通用框架:助手起草,主模型验证
投机解码(Speculative Decoding)先用一个计算便宜的机制,提出一段候选 token,再让主模型在一次前向计算中验证多个位置。因为候选内容已经给定,验证这些位置可以并行进行,不必像普通生成那样,每确定一个 token 才发起下一轮主模型计算。
直观地说,就是先让助手起草,再交给主模型审阅。若连续多个候选都通过,一次主模型验证就能推进多个最终 token;如果很快被拒绝,则丢弃后续草稿,从拒绝处修正并继续。
先分清两个概念:贪心解码每步选概率最高的 token;随机采样则按概率抽取。 比如两个候选的概率分别是 70% 和 30%,贪心选前者,随机采样则两者都有机会。它们决定“选哪个”,投机解码解决“怎样更快”,不是同一种分类。
所谓“无损”,就是加速但不改变主模型原本的选择规则:贪心模式下,结果要与逐个生成一致;随机采样下,经过正确的验证与校正,各种结果出现的概率应保持不变,但每次回答不必逐字相同。
速度也要算成本。像助手起草、主编审稿:草稿大部分能用,才省事;总要退回重写,反而更慢。投机解码同样要为起草、验证和缓存付出时间与显存。只有草稿被连续接受得足够多,省下的主模型计算轮次才可能抵过这些开销。 草稿准确率低、批量较大或引擎支持不佳时,都可能不升反降。
MTP(多 token 预测):草稿不一定来自独立的小模型
前面说,投机解码需要一个助手先写草稿。这个助手不一定是另一个小模型,也可以是主模型自带的预测模块。 MTP(Multi-Token Prediction,多 token 预测)就能提供这种能力:训练时,不只让模型学习预测下一个 token,还让额外模块学习预测后面几个 token。
沿用“助手起草、主编审稿”的比喻:独立草稿模型像外请的助手,原生 MTP 模块像自带的助手。用于投机解码时,它先猜后面几个 token,再由主模型验证;猜出来的内容不能直接当作最终答案。
所以,MTP 可以负责“写草稿”,投机解码负责“起草后验证”,两者可以配合,不是互相替代。 能猜几步、是否并行、最终快多少,要看具体模型和推理软件;自带助手也有开销,并不保证固定的加速倍数。
DFlash:让小模型同时起草多个 token,再由主模型验证
有些草稿模型仍要一个 token 接一个 token 地写,起草本身也会拖慢速度。DFlash 用块扩散方式,让小模型一次计算就提出一整块候选,像把“填完一个空,再填下一个”改成“一次填一排空格”。
为了猜得更准,DFlash 还把主模型部分层的中间计算结果提供给草稿模型。好比主编先给助手一份参考笔记,助手不必完全从头理解上下文,再将草稿交回主编审核。技术说明
所以,DFlash 不只是让主模型批量审稿,也让助手批量起草,并借主模型的信息提高准确率。 最终输出仍须通过验证;草稿模型虽小,权重和缓存也要占显存,不能当作零成本。
DFlash 2:让同时起草的 token 更连贯,提高草稿通过率
一次填一排空格,容易出现“每个词单看合理,连起来却不通顺”,也可能越填到后面越不准。DFlash 2 用两项改进来缓解这些问题。
路径选择器像在挑词组句:每个位置先保留几个候选,再比较相邻候选的搭配,选出更连贯的一串。局部卷积则让相邻位置共享一点信息:每个位置计算时,也参考前一个位置的中间结果,减少各猜各的、后半段容易出错的问题。两者都只是改善草稿,最终仍要由主模型验证。技术说明
效果可以看“每轮验证能推进多少个 token”。例如,官方 Qwen3.8-27B 的一组测试中,块大小设为 8,平均每轮推进 4.80 个 token。这不等于快了 4.80 倍,因为起草和验证本身也耗时。实验说明
实际提速还看使用场景:同一模型卡中,单请求时的输出吞吐约为普通逐个生成的 2.67~3.43 倍,32 个请求并发时则约为 1.01~1.45 倍。这些数字按总输出量除以请求全程耗时计算,不是纯生成阶段的速度,也不代表你的 16GB 显卡能达到同样效果。测试说明
DFlash 让草稿写得快,DFlash 2 进一步让草稿接得顺、通过得多,争取减少主模型的计算轮次。 真正部署时,仍要确认主模型、草稿模型、量化格式和推理软件能配套,并为草稿留下显存空间。
七、回到 16GB:预算是否成立,性能如何验证

图 7:容器被不同大小的方块刚好填满,指示条接近满格——预算很紧,任何漏项都可能让方案失败。

显存:算得下,还要留余量。“恰好装满”,并不是安全方案



把前面的权重、缓存和加速开销放到一起,就能算出一份显存预算。下面沿用原始材料的估算数演示,不是实测配置;具体模型文件、草稿配置和推理软件版本尚未明确。

项目

示例预算

使用前需要确认

主模型

约 11GB

加载后占多少显存,量化后回答是否可靠

草稿及相关开销

约 1.1GB

是否算上草稿的权重、缓存和临时计算空间

100K 上下文缓存

约 1.9GB

缓存用什么精度,实际占用多少显存

引擎与其他运行预留

约 2GB

是否够用来容纳运行中的临时数据

合计

约 16GB

几乎没有额外余量,不代表能稳定运行



加起来刚好 16GB,不等于能稳定运行。 这像把行李箱塞得刚好合上,途中再添一点东西就装不下了。表中任何一项低估,都可能超出容量。实际应统一 GB 与 GiB 的计量口径,以系统显示的可用显存为准,并检查运行时的最高占用。

上下文拉长,预算还会变化。假如缓存从约 1.9GB 增到约 5GB,其他项目不变,总计就达到约 19.1GB。这里仍是估算,但说明了一个关键区别:模型支持长上下文,不代表你的显卡装得下。

预算超了,可以缩短上下文、换更小或更低比特的模型、关闭草稿加速,或者让 CPU 分担一部分。每次调整后都要重看质量和速度,不能为了塞进加速器,先把主模型压到不好用。

速度:每秒写得快,不等于整项任务同比变快



原始材料记录:不开 DFlash 2 时为 27.86 token/s、10 分 54 秒;开启后为 49.96 token/s、2 分 40 秒。缺少完整日志与环境说明,这组数字只能用来说明比较方法,不能当作已复现的对照实验。

每秒生成速度约变成 1.79 倍,前后总耗时之比却约为 4.09 倍。为什么差这么多?像两个人抄文章:一个人更早写完,不一定全是手速快,也可能是文章更短、准备时间更少。模型也是如此:输出长度、输入处理、缓存命中,以及是否计入加载时间,都会影响总耗时。

所以,不能仅凭这组记录就说“投机解码让模型少想了”。它加快的是生成过程,不保证每次回答一样长;即使生成更快,输入处理和工具调用等环节仍然要花时间。

公平的比较,应在同一套硬件、主模型、提示词和生成设置下,只改变是否开启草稿加速。记录输出 token 数、开始回答前的等待时间、生成速度、总耗时、显存最高占用和答案质量;加载、预热与思考内容的计时口径保持一致,随机采样时多测几次。

显存要算全,还要留余量;速度要在相同条件下比较,还要看答案质量。 先确认模型好用,再判断加速值不值得开。


八、关键概念速查:每个词对应哪个问题

图 8:这些概念不是孤立的术语,而是同一根技术链条上可以互相组合的模块。

概念

回答的问题

不能忽略的边界

稠密 / MoE

每个 token 经过怎样的计算路径,调用多少专家?

激活参数少,不代表全部权重占用同比减少

权重量化

模型权重如何少占空间?

低比特可能影响质量,文件大小不是运行显存

分层卸载

GPU 放不下时,能否借助 CPU 与内存?

容量换取速度,影响程度需实测

KV Cache

怎样复用已经处理过的上下文?

长度、KV 头数、精度与并发都会影响占用

混合注意力

能否减少保存完整历史 KV 的层?

属于模型架构,其他状态仍然占空间

Prefill / Decode

慢在读输入,还是写输出?

两个阶段瓶颈不同,不能共用一个加速倍数

MTP

能否用模型自带模块预测后续 token?

可以用于投机起草,效果取决于模型和引擎

投机解码

一次主模型验证能否推进多个 token?

正确验证才能保持目标分布,也有额外成本

DFlash / DFlash 2

怎样并行起草,并提高候选的衔接与接受率?

需要配套草稿与后端,收益随任务和并发变化




结语:装得下只是起点,好用才是目的



本地部署,先看模型能不能答好你的问题,再看显存能否装下权重、上下文缓存和运行开销,最后才是用 MTP、DFlash 等方法争取提速。模型不是越大越好,加速也不是开了就一定有效。

下次看到“16GB 能跑 27B”,别只问每秒能生成多少 token。还要看它用了什么模型和量化、能处理多长的输入,以及在你的硬件上表现如何。最终要回答的是:答案是否可靠,运行是否稳定,完成任务要等多久?














本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注公众号

相关侵权、举报、投诉及建议等,请发 E-mail:2776601884@qq.com

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.|青ICP备2025004122号-1

在本版发帖
关注公众号
返回顶部