8GB显存跑35B大模型:量化、分层卸载与推理优化实战

发布时间:2026/9/29 23:32:59
8GB显存跑35B大模型:量化、分层卸载与推理优化实战 1. 先算明白账8GB 显存为什么敢碰 35B1.1 模型大小不是按“参数个数”估的我们常说的“35B 模型”指的是参数量在 350 亿左右。要估一个模型加载需要多少显存最简单粗暴的公式是参数量乘以每个参数的存储位数再除以 8 转成字节。如果直接用半精度FP16/BF16每个参数占 2 字节那么 35B 模型光权重就是 70GB。加上推理时的 KV cache、临时激活值实际占用还要再往上走。这个差距非常大8GB 显存连零头都不到。但这块数字也让很多人误以为“8GB 跑 35B 不可能”。真正让 8GB 显卡有机会上场的是量化推理以及“部分计算放到内存里”的混合运行模式。需要注意量化降低的是权重体积而不是“模型必须全部塞进显存”这件事。1.2 量化“压缩”了多少目前最常见的开源量化格式是 GGUF由 llama.cpp 生态推广常见的有 Q2_K、Q3_K_M、Q4_K_M、Q5_K_M、Q8_0 等。粗略按“每参数占用”估算Q2_K每个参数约 2.7 bitQ3_K_M每个参数约 3.5 bitQ4_K_M每个参数约 4.8 bitQ8_0每个参数约 8.5 bit按 35B 参数估算Q4_K_M 的权重大约是 21GBQ3_K_M 大约是 15GBQ2_K 大约是 12GB。哪怕把量化压到 Q2_K单看模型体积也仍然超过 8GB。也就是说只靠显存跑 35B 是没戏的必须把一部分层放到内存里。这听起来像“作弊”但实际正是 llama.cpp 这类框架设计好的能力分层卸载offload显存放得下多少层就放多少层放不下的留在内存由 CPU/GPU 协同完成前向计算。打个比方显存是小水箱内存是大水池模型数据是被抽上来的水。出水速度取决于水管粗细和泵的功率。8GB 跑 35B 相当于用小水管慢慢抽水能出来但别指望流速很快。1.3 “8GB 跑 35B”的本质是妥协讲清楚上面的计算你就能明白“8GB 跑 35B”并不是什么神奇黑科技而是在显存不足的情况下用内存带宽和时间换取“能运行”的可能。用它能跑不代表能用得舒服。后续所有调参、改造都围绕一个问题展开如何让少得可怜的显存被更高效利用同时不让 CPU 端的内存带宽成为压倒性的瓶颈。这里还要提一句标题里的“35B”其实是指 30B 到 40B 这个参数档位。目前热门开源模型里 Qwen2.5-32B、Yi-34B 都属于这个区间量化后体积和“35B”基本在同一档。下面的实操命令以 Qwen2.5-32B 为例逻辑可以平移到其他同类模型。2. 部署方案为什么我选了 Ollama 而不是直接上 llama.cpp2.1 不同工具怎么选带动本地大模型现在有三个主流方向一个是底层的 llama.cpp另一个是封装好的 Ollama底层仍然是 llama.cpp还有 LM Studio 这类带界面的工具。如果你是想折腾技术细节可以直接用 llama.cpp 去编译源代码手动指定每个参数如果你想快速复现一次“8GB 跑大模型”的实测Ollama 是更省心的选择。它把模型拉取、量化格式、上下文处理都集成好了几条命令就能进入交互界面。我在这个项目里选了 Ollama 还有一层原因它的日志对排查问题非常友好。跑起来之后你能在日志里直接看到“已卸载多少层到 GPU”“KV cache 占了多少”这类关键信息。这对调试 8GB 显存这种极限场景特别重要。2.2 我的机器配置与系统环境显卡NVIDIA8GB 显存2060 或同级CPU支持 AVX2 的 x86_64 处理器8 核心内存32GB DDR4 双通道系统Ubuntu 22.04 官方驱动Ollama 版本0.1.32 以上强调双通道内存是因为 CPU 跑大模型时内存带宽直接决定每秒能“喂”给模型多少参数。DDR4 双通道的实际带宽大约 20-30GB/s单通道会直接减半差距非常大。如果你手里是单根内存条建议先别急着跑 35B7B 模型会更现实。2.3 这次用哪个模型实测模型是 35B 这个档位里最常见的开源模型我机器上跑得比较多的是 Qwen2.5-32B量化格式为 Q4_K_M。Ollama 拉取时通常默认选择 Q4_K_M 版本正好符合我在 8GB 显存场景下的预期。模型体积大约 20GB加上 KV cache 和运行时 overhead对内存的要求大约是 24-28GB。我的 32GB 内存刚好够用但已经非常紧绷。3. 完整实操从拉取模型到调出可用配置3.1 先用默认参数把模型拉下来安装好 Ollama 后我做的第一件事是直接默认参数跑起来。命令很简单ollama run qwen2.5:32b这会把 Q4_K_M 量化版本拉到本地并在终端进入聊天界面。我先输入“你好”观察输出速度。第一次结果非常慢而且通过 nvidia-smi 看显存占用只有大约 3GB说明大部分层都跑在 CPU 上。这个状态能用但生成速度只有 1.x token/s用起来急死人。于是我先退出交互查看当前加载情况。Ollama 提供了一个很实用的命令ollama ps输出里能看到当前加载模型的“PROCESSOR”列如果显示 100% CPU / 0% GPU就说明 GPU 没有参与计算。8GB 显存只用了 3GB明显是默认策略太保守导致模型完全跑在内存里。3.2 手动指定 GPU 层数Ollama 默认是根据显存安全冗余来判断放多少层到 GPU所以它倾向于保守。这里需要手动干预。我新建了一个 Modelfile内容如下FROM qwen2.5:32b PARAMETER num_ctx 2048 PARAMETER num_gpu 22然后执行ollama create qwen32b-ngl22 -f Modelfile ollama run qwen32b-ngl22这里 num_gpu22 的含义是“把模型前 22 层放到 GPU”剩余层留在 CPU。具体该设多少没有标准答案需要用显存占用倒着调。我的方法是先把 num_gpu 设为 20跑一个比较长的回答让模型进入推理状态再观察 nvidia-smi。如果显存峰值在 7.2GB 左右说明还有余量可以继续加 2 层如果出现 CUDA out of memory 的报错就减 4 层。注意不要一上来就设很大的 num_gpu因为 KV cache 也会占显存上下文越长KV cache 越大。我把 num_ctx 固定在 2048就是为了给 KV cache 留出余量避免回答到一半显存爆掉。3.3 把上下文长度降到合理范围上下文长度num_ctx是很多“8GB 跑大模型失败或被卡死”的主要凶手。默认情况下Ollama 可能使用 4096 甚至 8192 的上下文长度这会为每个 token 在缓存中占一块空间。对 8GB 显存的机器来说把上下文压到 2048甚至 1024能直接减少 1GB 左右的显存开销。如果你希望温度等生成参数也能保留下来可以把它们一并写进 ModelfileFROM qwen2.5:32b PARAMETER num_ctx 2048 PARAMETER num_gpu 22 PARAMETER temperature 0.7这样一套配置下来显存占用通常会到 6.5-7GB处于 8GB 显卡的安全线内。注意这个数字不是固定的它由层数、上下文长度、量化格式共同决定。3.4 看日志确认参数真的生效Ollama 的日志在 Linux 上可以通过journalctl -u ollama或直接看/var/log/ollama.log查看。日志里会出现类似这样的行llama_model_load: ... offloaded 22/64 layers to GPU llama_kv_cache_init: ... CPU buffer size ... decode speed: 3.1 tokens/s这行“offloaded 22/64 layers to GPU”就是最关键的确认信息说明我们的参数生效了。我从纯 CPU 的 1.x token/s提升到 offload 22 层后的 3.x token/s进步很明显。当然如果继续加到 30 层速度可能更快但显存极可能不够机器会直接抛错。4. 实测数据与真实体验4.1 不同参数下的速度对比为了让你对速度差异有直观感受我把同一台机器上不同 num_gpu 的实测数据整理成了一张表不同机器数据会有差异但趋势一致num_gpu显存占用生成速度结论0约 2.2GB1.4 token/s纯 CPU能跑但很煎熬10约 3.8GB1.9 token/s略好一点价值不大22约 6.5GB3.1 token/s速度和显存比较均衡38约 8.0GB4.6 token/s显存马上到红线容易 OOM满层大于 8GB无法启动不能直接用从表里可以看到一个关键点并不是把层数加到最大就一定最好。在 8GB 显卡上22-30 层左右往往是最佳区间再往上显存随时有溢出风险。一旦溢出需要重启模型反而更浪费时间。4.2 生成速度的体感3 token/s 是什么概念每秒钟蹦出 3 个字。要输出一段 200 字的回答需要一分多钟。如果模型带思维链它在“思考”阶段也会以文字形式输出你看着像在打字但实际是模型在推理。体验虽然远不如云端 API但作为本地测试和隐私优先场景已经可用了。更让人难受的不是“慢”而是“看起来像卡死”。因为模型先对用户输入做 prompt processing这个阶段速度很快几十 token/s 很正常然后进入生成阶段突然掉到 3 token/s。你盯着终端错觉就是模型没反应了。我后来习惯写一个带计时的小脚本或者直接看终端右侧时间等待时心里有底。4.3 显存和内存的实时占用跑起来后我同时开了两个终端一个在跑模型另一个在轮询显存watch -n 1 nvidia-smi实际观察结果GPU 显存占用约 6.5GB内存占用约 24GB。这里有个容易被忽略的问题当模型很大部分在 CPU 上时内存带宽被打满CPU 占用也居高不下。如果你边跑模型边做其他计算整个机器都会变得卡顿。所以实测时我基本关掉了浏览器和其他后台任务专心等一个回答。5. 常见问题与排查技巧实录5.1 模型启动后系统内存直接爆掉这是我第一次用 8192 上下文启动时遇到的问题。模型还没完全加载完Linux 的 OOM Killer 直接把 ollama 进程杀了。原因很简单权重 20GB 已经压在内存上再加上 KV cache 和系统其他开销32GB 内存根本不够。解决办法是降低 num_ctx 到 1024 或 2048也可以考虑用更小的量化版本比如 Q3_K_M。千万不要以为 32GB 内存很充裕35B 模型默认配置分分钟把它耗尽。5.2 明明改了 num_gpu显存却不动修改 Modelfile 后一定要重新执行ollama create生成新模型再运行新名字。有几个版本对 Modelfile 的参数校验不严格如果直接沿用旧的模型名可能读到缓存配置。可以用ollama ps再确认一次当前进程的处理器分配如果还是 CPU检查日志里是否显示 offload 层数。这个坑我踩过两次后来养成了“每次改参数就换一个模型名”的习惯。5.3 回答到一半速度突然变得极慢如果机器开始疯狂读写磁盘基本可以判断是发生了内存交换swap。原因是某些配置下内存占用超过了实际物理内存系统把部分数据换到磁盘。由于模型权重每次生成时都要重新读取如果被换到磁盘速度会跌到 0.5 token/s 以内基本不可用。解决办法是打开free -g看可用内存关掉不必要的大进程或者把上下文继续调小。5.4 换到 Q2_K 后模型“降智”太严重我曾试图用更小的 Q2_K 量化来获得更快速度结果回答质量明显下降。35B 的 Q2_K 虽然能省出更多内存空间但模型的常识连贯性和逻辑都打了折扣。建议如果显存只有 8GB还是优先保 Q4_K_M 或 Q3_K_M别用 Q2_K。毕竟我们费这么大劲跑本地模型是为了推理质量而不是单纯的数字游戏。5.5 为什么别人说 8GB 能跑“很大”的模型网上很多人说 8GB 显存能跑 70B 甚至更大其实都是同一套逻辑大权重放内存GPU 只做部分加速。这与“完全在显存内运行”是两码事。作为技术测试可以玩但真实项目里我更推荐按任务需求选模型写代码和翻译用 7B-14B 已经足够流畅跑 35B 主要是为了获得更强推理能力但必须接受它的慢。我个人在实际操作中最深的感受是这个实验让我真正理解了显存、内存带宽和大模型推理之间的物理边界。以前看论文觉得量化很抽象亲手把 35B 压到一台 8GB 显卡上跑起来之后才知道每一步参数调整都是在跟硬件极限做交换少一点上下文就多一分稳定多一些 GPU 层就快一点点但风险也随之上升。如果你也想试建议先用 Q4_K_M 默认跑一遍纯 CPU 版本记录速度再逐步增加 num_gpu 找到自己的最佳点。亲手试一次比看任何教程都更容易上手。