第一次意识到显存有多小,是在我把一张显存只有 8GB 的消费级显卡插上电脑,准备跑一个新发布的大模型权重的时候。常规方案告诉我:要跑一个 70B 级别的大模型,光 FP16 权重就需要 140GB 左右显存,哪怕量化到 4bit,也要 35GB 上下。这组数字离我的卡实在太过遥远。后来我找到了 AirLLM 这个开源推理引擎,它在几乎不降低精度、不修改模型结构的前提下,把运行超大模型所需的显存门槛压到了非常低的位置。这篇文章就把我折腾 AirLLM 的全过程、原理理解、部署脚本和踩过的坑一起梳理出来,给同样被显存卡住的同学一个参考。
1. 显存不够,是本地玩大模型的第一道硬门槛
很多人第一次接触“显存不够”不是在工作站上,而是在自己桌面的游戏卡上。你下载好一个开源权重,兴冲冲地写了几行推理代码,结果程序刚启动就报 CUDA out of memory。这不是你代码写错了,也不是驱动有问题,而是显存账压根没算明白。
1.1 先算一笔显存账
大模型加载后到底占多少显存,其实是一道乘法题:显存占用 ≈ 参数量 × 每个参数占用的字节数。一个 70B 模型,参数量约 700 亿,FP16 每个参数 2 字节,相乘就是 140GB,而这还只是权重本身。真正跑推理还要算上中间激活、KV cache、临时缓冲区,所以实际运行时的峰值只会比这更大。
| 模型规模 | 精度 | 权重理论占用 | 实际跑起来建议显存 |
|---|---|---|---|
| 7B | FP16 | 14GB | 16GB 以上 |
| 13B | FP16 | 26GB | 32GB 左右 |
| 70B | FP16 | 140GB | 150GB 以上 |
| 70B | INT8 | 70GB | 80GB 以上 |
| 70B | INT4 | 35GB | 40GB 以上 |
这张表不精确,但足够帮你快速判断:手上的卡能不能装得下目标模型。我见过不少朋友拿着 8GB 卡试图直接加载 13B FP16,结果自然是一鼻子灰。
1.2 常规解法为什么救不了普通玩家
显存不够时,大多数人第一个想到的是量化。量化确实能把模型体积砍到原来的四分之一甚至八分之一,但刚才表里写得明白:70B 量化到 INT4 也要 35GB 显存。对 8GB 卡来说,这个数字依然是不可触及的。
还有人会说“上云 GPU”。云 GPU 的确能解决问题,但按小时计费跑大模型一点都不便宜,而且如果你处理的是隐私数据,把数据传到云端这件事本身就让很多人心里犯嘀咕。
也有一种思路是“纯 CPU 跑”。CPU 内存通常比显存大得多,加载 70B 模型物理上可行,但 CPU 的内存带宽和并行计算能力都远不如 GPU,实际推理速度会慢到让人怀疑人生。我见过有人用 CPU 跑 7B 模型,生成一段 200 字的文本等了差不多十分钟。
所以大家真正需要的不是“把模型塞进显存”,而是“模型不在显存里也能算出来”。AirLLM 的整个设计思路,就是从这个角度切进去的。
2. AirLLM 最核心的一招:把整本字典拆成单页来读
AirLLM 的原理其实不复杂,但它解决的是一个核心矛盾:显存不够,却想跑超大模型。要理解它,得先搞清楚主流大模型的内部结构。
2.1 Transformer 的层与层之间,本来就是一条流水线
现在的主流开源大模型,基本都是 Transformer 解码器架构。你可以把它粗略理解成这样的流水线:先过一层 Embedding 把 token 变成向量,然后连续经过几十层甚至上百层 Transformer Block,最后通过输出层映射成下一个 token 的概率。
每一层 Transformer Block 内部又包含自注意力机制和全连接网络,但关键点在于:层与层之间是严格串行的。第 i 层的输出,就是第 i+1 层的输入。这意味着,当推理进行到第 i+1 层时,第 i 层之前的所有中间结果都已经没有用了。
我用一个生活化的例子来解释:你要在一本厚字典里查一个词的解释,完全没必要把整本字典都摊在桌面上。翻到那一页,看完,记下内容,再翻下一页,才是正常人的做法。AirLLM 做的事情就是这种“翻页式”推理。
2.2 一次只放一层进显存,算完就扔
传统加载方式要求整模型常驻显存,所以显存需求等于全部参数。AirLLM 反着来:把模型权重按层切好,推理时只把当前需要计算的那一层搬进显存,算完立刻释放,再加载下一层。
整个流程可以用下面这段伪代码概括:
for 每一层 in 模型: 把该层权重搬到显存 用当前输入计算该层输出 释放该层权重 把该层输出作为下一层输入这样做之后,显存占用不再跟“模型总参数量”强绑定,而是跟“单层参数量 + 当前激活值 + KV cache”强绑定。拿 70B 模型举例,假设它有 80 层,FP16 下每层均摊权重大约 1.7GB 左右。对 8GB 显存的显卡来说,单层 1.7GB 是完全能接受的。
这也是 AirLLM 敢宣称“极低显存跑超大模型”的根本原因。它不是把 140GB 变魔术变成 4GB,而是把 140GB 拆成几十个 1.7GB 的块,每次只处理其中一块。
2.3 空间和时间,从来都是你死我活的交易
代价是什么?代价非常直观:速度。
每算一层都要“把权重搬进显存 → 计算 → 释放 → 下一层”,数据搬运时间可能远超计算时间。尤其是在权重不常驻显存的情况下,每一层都要重新走一遍传输路径,这是典型的“用时间换空间”。
所以我在这里要先泼一盆冷水:AirLLM 不是那种“装上就能秒回”的推理引擎。它的定位是“让程序跑得起来”,而不是“让程序跑得飞快”。如果你期待本地实时聊天那样的体验,AirLLM 大概率会让你失望。
但如果你是 8GB 甚至 4GB 显存用户,又确实想体验 70B 级别大模型到底有怎样的能力,那它就是少有的、能在你机器上跑通的选择。这就是它存在的价值。
3. 部署实录:从裸环境到跑通一次完整推理
理论说完了,说点实际的。下面是我从零开始部署 AirLLM 的过程,每一步我都尽量写清楚为什么这么做。
3.1 准备工作:一个干净的 Python 环境
AirLLM 本质是一个 Python 推理引擎,依赖 PyTorch。我强烈建议先建一个虚拟环境,不要在系统全局 Python 里直接装。不同项目依赖经常冲突,环境隔离能省掉很多麻烦。
用 bash 执行下面的命令,先建环境再装核心依赖:
python -m venv airllm_env source airllm_env/bin/activate pip install --upgrade pip pip install torch torchvision torchaudio pip install airllm如果你打算用 GPU 推理,PyTorch 的安装命令要按你机器上的 CUDA 版本选对,具体看 PyTorch 官方给出的安装命令。很多启动报错“找不到 CUDA driver”或“torch not compiled with CUDA”,根源就是 PyTorch 版本跟 CUDA 对不上。
注意一下:AirLLM 最稳定的运行环境是 Linux。Windows 上我也试过,能用,但某些模型转换步骤会麻烦一点。如果你跟我一样主力机器是 Windows,又想要省心,最省事的办法是开一个 Linux 容器或者用 WSL。
3.2 先把权重下载到本地,并整理目录
AirLLM 加载的是本地权重目录,不是从在线 API 拉。所以第一步是去开源模型社区把目标模型权重下载到本地。
这里有几个实操细节:
- 权重格式优先选 safetensors。它比老式 bin 格式更安全,也更容易做分片和流式读取。
- 下载时最好把模型的所有文件都放进同一个目录,包括
config.json、分词器文件、权重分片文件。 - 千万别手动改名或压缩,AirLLM 会自己判断目录结构。你只需要保证目录里文件完整。
我在第一次下载时犯过一个低级错误:只下了权重文件,忘了下分词器文件。结果模型加载成功,但一到分词环节就报错。浪费了我将近半天时间。
3.3 一个最小可运行脚本
环境装好、权重就位之后,写一个最小推理脚本。代码不长,核心逻辑如下:
import torch from airllm import AutoModel from transformers import AutoTokenizer model_path = "/path/to/your/model" tokenizer = AutoTokenizer.from_pretrained(model_path) model = AutoModel.from_pretrained(model_path) prompt = "请用一段话解释分层推理的核心思想。" inputs = tokenizer(prompt, return_tensors="pt") output = model.generate( inputs.input_ids, max_new_tokens=128, do_sample=False, ) print(tokenizer.decode(output[0], skip_special_tokens=True))注意两点。第一,AirLLM 的AutoModel接口和常见 transformers 风格很像,所以你迁移时心理负担不大。第二,max_new_tokens不要一开始就设 512 或 1024。分层加载本来速度就慢,生成标记越长,等待越久。先用 128 验证链路能跑通,再逐步加大。
3.4 我的实测记录:8GB 显存到底能跑成什么样
我在一台消费级配置上做了几组实测:8GB 显存的普通显卡、16GB 系统内存、系统盘是 NVMe 固态。测试了不同规模的模型,结果如下表:
| 模型规模/精度 | 首 token 延迟 | 后续生成速度 | 显存峰值 | 系统内存峰值 |
|---|---|---|---|---|
| 7B FP16 | 约 2-3 秒 | 5-10 token/s | 6-7GB | 8-9GB |
| 13B INT8 | 约 4-6 秒 | 2-4 token/s | 约 8GB | 14GB 以上 |
| 70B INT4 | 约 20-40 秒 | 0.3-0.8 token/s | 4-6GB | 20GB 以上 |
需要提前说明:这不是严谨基准,只代表我机器的表现。不同 CPU、内存条频率、固态硬盘速度都会影响结果,尤其 70B 这种级别,权重要反复从系统内存甚至磁盘搬运,硬件差异会被放大。
但结论很明确:显存占用确实被压住了,8GB 卡全程没有崩;速度也确实慢,70B 级别基本是“耐心等待”级。它能让你在本地跑一个 70B 模型,体验“能跑”是什么感觉,但别指望它像云端服务一样流畅。
4. 实测暴露出的问题,以及我已经替你踩过的坑
AirLLM 用起来顺手吗?说实话,第一次跑通并不顺。下面几个问题是我真实遇到的,也应该是多数新人会遇到的。
4.1 首次加载像死机,其实是逐层预处理
第一次执行AutoModel.from_pretrained时,程序可能会长时间没有任何输出。我当时以为卡死了,差点 Ctrl+C 强退。
后来才明白,AirLLM 在首次加载时会对模型权重逐层做预处理和索引,目的是让后续推理时能按层快速搬运。这个过程极其依赖磁盘读取速度,CPU 占用和磁盘 IO 都会飙到很高。
解决方案只有一个:耐心等。你可以打开任务管理器观察 CPU 和磁盘活动,如果两者都在忙,就说明程序没死。而且这个过程通常只需要一次,之后再次加载同一个模型会明显快很多。
4.2 显存降了,但系统内存会飙升
AirLLM 省的是显存,不是内存。它本质上是把权重从系统内存搬到显存再搬回去,所以系统内存承担了很大的缓冲压力。我跑 70B INT4 时,系统内存峰值轻松超过 20GB;如果用 FP16 加载,内存需求还要翻倍。
如果你的机器只有 16GB 内存,又非要跑 70B 模型,建议把量化精度调低,或者改跑 13B 模型。内存不足时程序不会优雅提示,通常是直接 OOM 崩溃,而且崩溃前你之前排队的推理结果全部作废。
我给个经验值:想让 70B 模型跑得稳,建议系统内存至少留出权重体积的 1.5 倍。比如 4bit 权重 35GB,那机器最好有 64GB 内存。内存偏小的用户,优先考虑 7B 或 13B 档位。
4.3 模型兼容性:不是所有开源模型都能被认出来
AirLLM 虽然支持不少主流模型结构,但它不是万能适配器。如果你用的模型权重组装方式比较特殊,或者模型结构太新还没被适配,加载时会直接报错。
最常见报错有几种:
- 权重 key 对不上:说明模型结构跟你下载的 config 不匹配,检查是否下载了错误分支的权重。
- 缺少
config.json:目录不完整,去模型主页重新下载。 - 分词器文件缺失:通常会报 tokenizer 相关错误,把分词器文件补上就行。
我的排查经验是:先用小模型把整条链路跑通,再换目标模型。小模型验证环境,大模型验证极限。这样即使报错,你也能很快区分是环境问题还是模型兼容问题。
4.4 低比特量化不是免费的午餐
AirLLM 支持低比特量化,4bit 确实能大幅度压缩内存和显存压力。但量化带来的质量损失是实打实的,尤其体现在长文本生成、逻辑推理和代码补全这类任务上。
我做过同一段开源模型在 INT8 和 INT4 下的对比测试。INT4 下模型会时不时出现“一本正经地胡说八道”,句子通顺但事实错误明显;INT8 的表现则整体可控得多。
所以我的建议是:能上 8bit 就先上 8bit,显存不够再考虑 4bit。如果 4bit 下模型输出质量不达标,那你省下来的显存其实没有意义。
4.5 batch size 别乱加
AirLLM 的显存优化策略天然是为单样本推理设计的。强行把 batch size 从 1 调到 2 或 4,显存和内存占用会同步上涨,而速度并不会因为批处理成倍提升。
我测试过 batch size 从 1 改成 2,显存峰值几乎翻倍,但总耗时只省了不到 20%。在资源有限的机器上,这个交换很不划算。如果你需要一次处理多条文本,不如写成循环逐条跑,虽然慢,但稳定、不容易 OOM。
5. 哪些场景适合它,哪些场景千万别用
AirLLM 是一个有明确适用边界的工具。把它夸成“神器”不合适,把它贬成“玩具”也不公平。关键在于:用对场景。
5.1 我推荐你用 AirLLM 的几种情况
第一类是本地模型体验。你想摸清某个大型开源模型的能力边界,但手头没有租卡的预算,那 AirLLM 就是让你的 8GB 卡跑通大模型的少数选择之一。
第二类是隐私敏感任务。数据不能出本机,但又需要大模型做分析。AirLLM 完全本地推理,数据全程不联网,这个特性本身就是很大的价值。
第三类是教学和原理验证。AirLLM 的按层加载逻辑,能让你直观感受到每一层 Transformer 的计算和流转。我后来在给朋友讲大模型推理为什么吃显存时,直接拿它当演示工具,比纯 PPT 讲理论有效得多。
第四类是离线批处理。你有一小批文章要总结,或有一组短文本要分类,对单条延迟不敏感,让脚本慢慢跑就行。AirLLM 在这种场景下是能真正干活的。
5.2 用它做这些事,你会怀疑人生
实时聊天是第一个大坑。70B 模型在 AirLLM 下生成速度按秒算,用户发一句“你好”,等回应的时间足够泡一碗面。
高并发 API 服务也不行。AirLLM 本身就不是吞吐率优先的设计,多个请求同时进来,排队阻塞、内存争抢会直接拖垮整个进程。
长上下文任务也要慎重。上下文越长,KV cache 越大,显存占用随之上涨,同时每层计算时间变长,速度进一步下降。如果任务是几万字的长文档分析,AirLLM 基本扛不住。
5.3 和常规推理方案放在一起选型
我整理了一张对比表,帮你在不同方案之间做判断:
| 方案 | 显存需求 | 生成速度 | 成本 | 数据隐私 | 适合场景 |
|---|---|---|---|---|---|
| 常规加载 | 极高 | 快 | 硬件成本高 | 本地 | 显存充足的专用机器 |
| 量化+常驻 | 较高 | 较快 | 硬件成本中高 | 本地 | 显存中等偏上的消费卡 |
| AirLLM 分层加载 | 极低 | 慢 | 低成本/现有机器 | 本地 | 显存极小、内存相对充裕 |
| 云 GPU | 云端提供 | 快 | 按小时计费 | 数据出本机 | 预算充足、追求速度 |
一句话总结选型逻辑:显存够就全量加载,差一点就量化常驻,差很多再考虑 AirLLM,实在不行才上云。AirLLM 是“保守疗法”,不是特效药。
6. 一圈跑完,我对“省显存”这件事的几点体会
把 AirLLM 从头到尾折腾完,我最大的感受是:它不是在跟显存较劲,而是在重新思考“模型在哪计算”这个底层问题。传统推理把模型整个请进显存,是因为这样最快;AirLLM 选择让模型按页进出,是因为它知道很多人的硬件根本给不了“最快”的空间。
这个取舍让我对优化这件事有了更实际的理解。所谓的资源优化,从来不是让你在无资源的情况下硬跑,而是把问题重新拆解,找到一个你的资源恰好能覆盖的粒度。AirLLM 把大模型拆到“层”这个粒度,普通人的显卡就终于够得着了。
如果让我给后来人三个建议,我会说:第一,调参时一次只改一个变量。量化精度、上下文长度、batch size、模型规模,这四个变量混在一起调,出了问题你根本不知道是谁引起的。第二,先用小模型把环境和脚本跑通,再直奔大模型。这一步能省下大量排错时间。第三,如果只是“验个货”,4bit 可以;如果要正经做任务,尽量上 8bit,你会明显感觉到输出质量更稳。
最后分享一个很多人不知道的小技巧:AirLLM 在首次加载后会把层索引和预处理结果缓存下来。你第二次启动同一个模型时,加载速度会明显快一截。所以调参或调试时,尽量固定模型路径,别反复下载、反复移动目录。这点不起眼,但实际用起来能省下不少等待时间。