一天一个开源项目(第207篇):AirLLM - 单卡 4GB 跑 70B 大模型

引言

"Run 70B model inference on a single 4GB GPU, without quantization, distillation or pruning."

这是"一天一个开源项目"系列的第 207 篇文章。今天带你了解的项目是 AirLLM

运行一个 70B 参数的大模型,常规思路是什么?买一张 80GB 的 A100,或者至少凑两张 40GB 的卡。要么量化,精度换显存;要么蒸馏,能力换体积。在大多数人的认知里,"大模型"和"消费级显卡"是两个互斥的概念。

AirLLM 用一个非常简单的洞察打破了这个假设:GPU 不需要同时持有整个模型,只需要持有当前在执行的那一层。

把模型按层拆分存到磁盘,推理时逐层加载到 GPU,用完立即释放,再加载下一层。所需显存从"模型总大小"变成"单层大小"------而单层通常只有几十到几百 MB。

结果是:

  • 4GB 显存跑 Llama 3.x 70B(全精度)
  • 8GB 显存跑 Llama 3.1 405B
  • 12GB 显存跑 DeepSeek-V3 671B
  • 3.72GB 显存跑 Kimi K3 2.8T

33.5k Stars,Apache 2.0,作者 Gavin Li 打造。

你将学到什么

  • 逐层流式加载(Layer Streaming)的核心机制
  • 为什么这种方法不需要量化也能大幅降低显存需求
  • Prefetching 如何通过重叠加载和计算提升吞吐
  • MoE 模型(DeepSeek-V3、Kimi K3)下的稀疏专家加载
  • 块量化压缩如何在不损失精度的情况下再提速 3 倍

前置知识

  • 知道什么是 Transformer 层结构
  • 了解 GPU 显存和模型大小之间的基本关系
  • Python 基础(能调用 HuggingFace API)

项目背景

项目简介

AirLLM 是一个 Python 库,让开发者可以在显存严重不足的 GPU 上运行远超其显存容量的语言模型。

它的核心主张简洁到令人意外:不改变模型结构,不量化权重,不蒸馏知识,只改变模型的加载方式

这个想法在今天看来显而易见,但它解决的问题是真实存在的:绝大多数开发者和研究者没有数据中心级别的 GPU 集群,却想在本地验证最新的开源大模型。AirLLM 让这件事在一张普通游戏显卡上成为可能。

作者介绍

  • 作者 : Gavin Li (lyogavin)
  • 背景: 独立开发者,专注于 LLM 推理优化
  • 理念: 让更多人能在消费级硬件上访问和研究顶级开源模型

项目数据

  • ⭐ GitHub Stars: 33,500+
  • 🍴 Forks: 3,500+
  • 📄 License: Apache 2.0
  • 💻 主要语言: Python
  • 📦 安装: pip install airllm

主要功能

核心作用

AirLLM 在 GPU 和模型文件之间插入一个"逐层调度器":

markdown 复制代码
磁盘(完整模型,按层分片存储)
    ↓  加载第 N 层
GPU(单层权重,几十到几百 MB)
    ↓  计算第 N 层的前向传播
    ↓  释放第 N 层
    ↓  加载第 N+1 层
GPU(单层权重,新层覆盖旧层)
    ↓  ...
输出 token

所需显存从"整个模型"缩减到"最大的单层",通常只有几百 MB 到 1-2 GB。

显存需求对比

模型 参数量 AirLLM 所需显存
Qwen3 / Mistral / Phi 等 8B 级 ~8B ~1--2 GB
Qwen3-235B(MoE) 235B ~3 GB
Qwen3.8-27B(密集 VL) 27B 3.33 GB
Kimi K3 2.8T 3.72 GB
Llama 3.x 70B(全精度) 70B ~4 GB
Qwen3.8-Flash-Next(MoE) ~180B 5.95 GB
Llama 3.1 405B 405B ~8 GB
DeepSeek-V3 671B ~12 GB

注意:MoE 模型(Kimi K3、Qwen3-235B、DeepSeek-V3)所需显存往往低于同参数量的密集模型,因为每个 token 实际激活的专家只是总参数的一小部分。

使用场景

  1. 消费级显卡本地研究

    • RTX 4090(24GB)本来跑不了 70B 全精度模型,用 AirLLM 可以轻松跑 405B。适合研究前沿模型能力的个人开发者。
  2. 本地私有数据推理

    • 不想把数据发到云端 API 的场景,用 AirLLM 在本地机器完成推理,数据不出本地。
  3. 多模型对比测试

    • 下载多个大模型,不需要考虑哪张卡能装哪个模型,统一用 AirLLM 的逐层加载方案跑。
  4. 苹果 Silicon Mac 用户

    • M 系列 MacBook 的统一内存架构天然适合逐层加载,AirLLM 原生支持 Apple Silicon + MLX。
  5. CPU 推理

    • 甚至不需要 GPU,可以纯 CPU 推理(速度更慢,但能跑)。

快速开始

bash 复制代码
pip install airllm

基础推理(AutoModel API):

python 复制代码
from airllm import AutoModel

MAX_LENGTH = 128
model = AutoModel.from_pretrained("Qwen/Qwen3-32B")

input_text = ["What is the capital of France?"]
input_tokens = model.tokenizer(
    input_text,
    return_tensors="pt",
    return_attention_mask=False,
    truncation=True,
    max_length=MAX_LENGTH,
    padding=False
)

generation_output = model.generate(
    input_tokens['input_ids'].cuda(),
    max_new_tokens=20,
    use_cache=True,
    return_dict_in_generate=True
)

output = model.tokenizer.decode(generation_output.sequences[0])
print(output)

AutoModel.from_pretrained 会自动检测模型类型,不需要手动指定是 LlamaModel 还是 QwenModel。

启用压缩(3 倍加速):

bash 复制代码
pip install -U bitsandbytes airllm
python 复制代码
model = AutoModel.from_pretrained(
    "meta-llama/Llama-3-70B-Instruct",
    compression='4bit'   # 或 '8bit'
)

MacOS Apple Silicon:

bash 复制代码
pip install mlx torch
pip install airllm

代码完全相同,AirLLM 自动检测平台并使用 MLX 后端。

核心特性

1. AutoModel:自动模型类型检测

不同的大模型有不同的架构(Llama、Qwen、DeepSeek 各不相同),原本需要手动指定模型类。AutoModel 会读取 HuggingFace 的 config.json,自动路由到正确的实现。

python 复制代码
# 这一行代码处理所有支持的模型架构
model = AutoModel.from_pretrained("any-supported-model-id")

2. Prefetching:重叠加载与计算

默认开启。GPU 在计算第 N 层时,后台线程同时从磁盘加载第 N+1 层------让 I/O 和计算并行,减少等待时间,提升约 10% 的吞吐。

python 复制代码
model = AutoModel.from_pretrained("model-id", prefetching=True)  # 默认开启

3. 块量化压缩

与标准量化不同,AirLLM 只对权重进行块量化,不动激活值。原因:

  • AirLLM 的瓶颈是磁盘加载速度,不是计算速度
  • 权重量化 → 文件更小 → 加载更快 → 整体速度提升
  • 只压缩权重,激活值保持全精度 → 精度损失更小,异常值不敏感

支持 4bit8bit 两种压缩级别,最高可达 3 倍推理加速

4. MoE 稀疏专家加载

对于 DeepSeek-V3、Kimi K3 这类 MoE(混合专家)模型,每个 token 只激活全部专家中的少数几个(路由专家)。AirLLM 只加载当前 token 实际激活的专家层,跳过未激活的专家------这正是 2.8T 参数的 Kimi K3 只需要 3.72GB 显存的原因。

5. 完整的配置参数

python 复制代码
model = AutoModel.from_pretrained(
    "model-id",
    compression='4bit',           # 权重压缩
    profiling_mode=True,          # 打印各层耗时
    layer_shards_saving_path="./shards",  # 分片存储路径
    hf_token="hf_...",            # 访问私有/门控模型
    prefetching=True,             # 重叠加载(默认开启)
    delete_original=True          # 删除原始下载文件节省磁盘
)

项目详细剖析

核心机制:为什么显存需求只和单层大小有关?

标准推理的显存占用由三部分构成:

  1. 模型权重:全部参数一次性加载到 GPU 显存
  2. KV Cache:注意力层的键值缓存(随序列长度增长)
  3. 激活值:中间计算结果

AirLLM 只解决第一个问题,方法是把"一次性加载"变成"按需加载":

ini 复制代码
传统方法(VRAM = 模型大小):
┌─────────────────────────────┐
│  Layer 1 weights             │
│  Layer 2 weights             │
│  ...                         │
│  Layer N weights    ← GPU VRAM(全部占满)
└─────────────────────────────┘

AirLLM(VRAM = 单层大小):
┌─────────────────────────────┐
│  Layer K weights (当前层)    │ ← GPU VRAM(只有一层)
└─────────────────────────────┘
磁盘上存储其余所有层

这个权衡是:以推理速度换显存。每层都需要一次磁盘到 GPU 的数据传输,整体速度远低于权重常驻显存的情况,但能让消费级硬件运行无法本地部署的模型。

层分片的存储格式

第一次运行时,AirLLM 会把 HuggingFace 下载的模型拆分成按层存储的分片文件:

erlang 复制代码
model_shards/
  ├── layer_0.safetensors
  ├── layer_1.safetensors
  ├── ...
  └── layer_N.safetensors

拆分是一次性操作,之后每次推理直接读取分片文件。delete_original=True 选项会在拆分完成后删除原始 HuggingFace 格式的文件节省磁盘空间(注意:删除后无法恢复)。

MoE 模型的特殊处理

以 Kimi K3(2.8T 参数)为例:

markdown 复制代码
Kimi K3 架构(简化):
每个 MoE 层包含 N 个专家(Expert)
每个 token 的路由器(Router)只激活 top-K 个专家

AirLLM 的处理:
1. 加载当前 MoE 层的路由器权重
2. 对输入 token 计算路由分数
3. 只加载 top-K 个被选中的专家权重
4. 执行前向传播
5. 释放所有权重

→ 实际加载量 = 路由器 + top-K 专家(远小于整个 MoE 层)

2.8T 参数的 Kimi K3 只需要 3.72GB 显存,正是因为每次推理只有极小一部分参数被激活和加载。

Prefetching 的工作原理

markdown 复制代码
时间轴(无 Prefetching):

第1层计算 → 等待第2层加载 → 第2层计算 → 等待第3层加载 → ...

时间轴(有 Prefetching):

第1层计算
    ↕(并行)
        第2层从磁盘加载到 CPU/固定内存

第2层计算(立刻开始,无需等待)
    ↕(并行)
        第3层从磁盘加载到 CPU/固定内存

第3层计算 ...

Prefetching 把磁盘 I/O 隐藏在计算时间内,实测约提升 10% 吞吐。

与量化方案的对比

方案 原理 对精度的影响 对速度的影响 显存需求
INT4 量化(GPTQ/AWQ) 权重 + 激活全部量化 有损失(需校准) 大幅提升 显著降低
AirLLM(无压缩) 逐层加载 无损失 慢(磁盘 I/O) 仅单层大小
AirLLM + 4bit 压缩 逐层加载 + 权重量化 轻微损失 3x 加速 仅单层大小

AirLLM 的定位不是替代量化,而是补充:量化优化计算效率,AirLLM 优化显存使用,二者可以结合。

常见问题与解决

MetadataIncompleteBuffer:磁盘空间不足,分层切割中断。清理 HuggingFace 缓存重试。

ValueError: max() arg is an empty sequence :使用了错误的模型类,换成 AutoModel 即可。

401 Client Error :访问门控模型(如 Llama 3)需要传入 hf_token

Padding token 错误 :tokenizer 调用时设置 padding=False


项目地址与资源

官方资源

  • 🌟 GitHub : github.com/lyogavin/ai...
  • 📦 PyPI : pip install airllm
  • 🤗 HuggingFace 兼容: 直接使用 HuggingFace model ID

相关资源


总结与展望

核心要点回顾

  1. 洞察极简:只保留当前执行层在 GPU 上,显存从"模型总大小"变成"单层大小"
  2. 零精度损失(默认模式):不量化不蒸馏,全精度推理,结果和正常推理完全一致
  3. MoE 天然适合:稀疏激活 + 逐层加载双重作用,2.8T 参数模型只需 3.72GB
  4. 块量化是可选加速器:只压缩权重,精度更友好,速度最多 3x 提升
  5. 一行代码支持所有架构AutoModel.from_pretrained(any_model_id) 处理所有支持的模型

适用人群

  • 想在消费级 GPU 上研究前沿大模型的开发者:RTX 4090 跑 405B,这是从前不可能完成的事
  • 需要本地推理但不想量化的研究者:保持全精度,结果可信
  • MacBook 用户:Apple Silicon 统一内存 + MLX 后端,无需独立显卡
  • 隐私敏感场景:数据不出本地,大模型推理完全在机器上完成

一句话评价

AirLLM 用一个反直觉的技巧证明了:大模型部署的门槛,从来不是参数量,而是同时持有多少参数------这件事可以改变。


欢迎访问 PrimeSkills ------ 一个精心策划的 AI Agent 与技能市场,所有内容均经过真实企业级工作流验证。没有噱头,只有真正有效的东西。

更多实用知识和有趣产品,欢迎访问我的个人主页

相关推荐
来让爷抱一个2 小时前
2026 智能体安全实战:把护栏写进SPEC,MonkeyCode 云端跑通
人工智能·安全·机器学习
冬奇Lab2 小时前
Code Agent 解剖(19):AgentTeams——一个实验系统的生与死
人工智能
行百里er3 小时前
Gateway 上别硬塞 MVC:DeferredImportSelector 看菜下锅
spring boot·后端·开源
curd_boy3 小时前
【Redis】Redis从缓存到AI向量平台
人工智能·redis·缓存
kyriewen3 小时前
GPT-6 发布当晚,三大 AI 集体宕机 4 小时——我扒完时间线,发现最该慌的不是宕机
人工智能·程序员·ai编程
十六年开源服务商3 小时前
2026年WordPress页面构建器终极选型指南
开源
GrepowTattu3 小时前
从2026世界机器人大会看机器人补能:为什么智能充电正在成为重要一环
人工智能·机器人
IT_陈寒3 小时前
React Hooks闭包陷阱差点让我加班到凌晨
前端·人工智能·后端
揽秀亭长3 小时前
视频转文字工具对比:从字幕生成到文本整理
人工智能·音视频