acorn-llm 0.9.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. acorn_llm-0.9.2/PKG-INFO +307 -0
  2. acorn_llm-0.9.2/README.md +279 -0
  3. acorn_llm-0.9.2/acorn/__init__.py +53 -0
  4. acorn_llm-0.9.2/acorn/__main__.py +145 -0
  5. acorn_llm-0.9.2/acorn/_autograd.py +296 -0
  6. acorn_llm-0.9.2/acorn/_kernels/__init__.py +475 -0
  7. acorn_llm-0.9.2/acorn/_kernels/acorn_int4.c +593 -0
  8. acorn_llm-0.9.2/acorn/_ops.py +700 -0
  9. acorn_llm-0.9.2/acorn/autobit.py +160 -0
  10. acorn_llm-0.9.2/acorn/bench.py +192 -0
  11. acorn_llm-0.9.2/acorn/chat.py +173 -0
  12. acorn_llm-0.9.2/acorn/eco.py +79 -0
  13. acorn_llm-0.9.2/acorn/gpu.py +343 -0
  14. acorn_llm-0.9.2/acorn/kvcache.py +75 -0
  15. acorn_llm-0.9.2/acorn/llama.py +691 -0
  16. acorn_llm-0.9.2/acorn/lora.py +98 -0
  17. acorn_llm-0.9.2/acorn/model.py +268 -0
  18. acorn_llm-0.9.2/acorn/pack.py +568 -0
  19. acorn_llm-0.9.2/acorn/prune.py +100 -0
  20. acorn_llm-0.9.2/acorn/runtime.py +345 -0
  21. acorn_llm-0.9.2/acorn/safetensors.py +167 -0
  22. acorn_llm-0.9.2/acorn/session.py +115 -0
  23. acorn_llm-0.9.2/acorn/shard.py +146 -0
  24. acorn_llm-0.9.2/acorn/speculative.py +84 -0
  25. acorn_llm-0.9.2/acorn/stream.py +158 -0
  26. acorn_llm-0.9.2/acorn/tokenizer.py +221 -0
  27. acorn_llm-0.9.2/acorn/train.py +154 -0
  28. acorn_llm-0.9.2/acorn/tui.py +335 -0
  29. acorn_llm-0.9.2/acorn_llm.egg-info/PKG-INFO +307 -0
  30. acorn_llm-0.9.2/acorn_llm.egg-info/SOURCES.txt +47 -0
  31. acorn_llm-0.9.2/acorn_llm.egg-info/dependency_links.txt +1 -0
  32. acorn_llm-0.9.2/acorn_llm.egg-info/entry_points.txt +2 -0
  33. acorn_llm-0.9.2/acorn_llm.egg-info/requires.txt +9 -0
  34. acorn_llm-0.9.2/acorn_llm.egg-info/top_level.txt +1 -0
  35. acorn_llm-0.9.2/pyproject.toml +44 -0
  36. acorn_llm-0.9.2/setup.cfg +4 -0
  37. acorn_llm-0.9.2/tests/test_seed.py +175 -0
  38. acorn_llm-0.9.2/tests/test_v02.py +263 -0
  39. acorn_llm-0.9.2/tests/test_v03.py +199 -0
  40. acorn_llm-0.9.2/tests/test_v04.py +259 -0
  41. acorn_llm-0.9.2/tests/test_v04b.py +139 -0
  42. acorn_llm-0.9.2/tests/test_v06.py +150 -0
  43. acorn_llm-0.9.2/tests/test_v07.py +120 -0
  44. acorn_llm-0.9.2/tests/test_v08.py +114 -0
  45. acorn_llm-0.9.2/tests/test_v09.py +85 -0
  46. acorn_llm-0.9.2/tests/test_v10.py +145 -0
  47. acorn_llm-0.9.2/tests/test_v11.py +100 -0
  48. acorn_llm-0.9.2/tests/test_v12.py +179 -0
  49. acorn_llm-0.9.2/tests/test_v13.py +66 -0
@@ -0,0 +1,307 @@
1
+ Metadata-Version: 2.4
2
+ Name: acorn-llm
3
+ Version: 0.9.2
4
+ Summary: Acorn — Big models. Tiny footprint. 以小搏大的 AI 运行与训练框架(INT4 压缩态推理 / KV int8 / 层流式 / 投机解码 / LoRA / 能效治理 / 零依赖核心)
5
+ Author: Acorn Contributors
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/yourname/acorn
8
+ Keywords: llm,inference,quantization,int4,transformers,qwen,llama,cpu
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
20
+ Requires-Python: >=3.9
21
+ Description-Content-Type: text/markdown
22
+ Provides-Extra: fast
23
+ Requires-Dist: numpy>=1.24; extra == "fast"
24
+ Provides-Extra: gpu
25
+ Requires-Dist: torch>=2.0; extra == "gpu"
26
+ Provides-Extra: dev
27
+ Requires-Dist: numpy>=1.24; extra == "dev"
28
+
29
+ <div align="center">
30
+
31
+ <img src="assets/logo.svg" width="160" alt="Acorn Framework Logo"/>
32
+
33
+ # Acorn Framework 🌰
34
+
35
+ **Big models. Tiny footprint. —— 芥子纳须弥,把大模型装进口口袋。**
36
+
37
+ *以小搏大的 AI 运行与训练框架:更小的空间 · 更快的速度 · 更少的痛苦*
38
+
39
+ ![status](https://img.shields.io/badge/status-v0.3--native--kernel-green) ![deps](https://img.shields.io/badge/core%20deps-0-blue) ![python](https://img.shields.io/badge/python-3.9%2B-blue) ![license](https://img.shields.io/badge/license-MIT-black)
40
+
41
+ </div>
42
+
43
+ ---
44
+
45
+ ## 为什么是 Acorn?
46
+
47
+ 模型越来越大,设备没有变大。7B 参数的模型以 FP16 存储要 **14 GB**,而世界上绝大多数设备只有 8–16 GB 内存。
48
+
49
+ Acorn 的信念:**推理和训练不应该被显存大小判处死刑。**
50
+
51
+ | 痛点 | Acorn 的回答 | 实测 |
52
+ |---|---|---|
53
+ | 模型放不进显存 | **int4 压缩态常驻**(0.5 B/参数,绝不物化 fp 矩阵)+ **层流式** | 7B = **2.91 GB**;流式 **154 MB**(省 19x) |
54
+ | 推理太慢 | **原生 AVX2 内核** + 常驻线程池 + RoPE + KV Cache + 投影融合 | 7B decode **4.7 tok/s**(带宽已到机器上限 72%) |
55
+ | 量化掉精度 | **AutoBit**:逐层敏感度实测(跨度 10⁵×)→ 字节预算下自动混合位宽 | 同预算 KL **↓87%** |
56
+ | 长上下文吃内存 | **KV Cache int8**(逐 token absmax 量化) | 内存 **28%**,输出偏差 0.4% |
57
+ | 模型太大 | **结构化剪枝 + 稀疏内核**(FFN 神经元幅度剪枝 + 位图跳零) | 50% 剪枝:字节 50%,**加速 x5.8**,loss 仅 x1.08 |
58
+ | 接不了真模型 | **safetensors 零依赖读写 + LLaMA 架构 + BPE 分词器 + 流式转换器** | 数值与独立参考实现一致(rel 1.5e-7) |
59
+ | 框架太重 | **零依赖核心**(NumPy 可选加速),纯 Python 也能跑全链路 | 0 依赖 |
60
+ | 训练门槛高 | **LoRA**:冻结基座只训适配器,合并后可直接打包 | 25.3% 参数学新语料 |
61
+ | API 记不住 | **3 行代码跑模型**,流式输出、top-k/top-p 开箱即用 | — |
62
+
63
+ ### 🖥️ v0.9:聊天室 UI + GPU 后端
64
+
65
+ ```
66
+ 交互式聊天(examples/chat.py):
67
+ • 思考流: [thinking...] 深灰显示思考 → [think done] → 正文
68
+ • 终端 Markdown 渲染(粗体/代码块/标题/列表, 零依赖 ANSI)
69
+ • 多轮对话跨轮 KV 复用 · /eco /spec /raw 命令
70
+
71
+ GPU 后端(acorn.gpu, torch CUDA):
72
+ • 发现并启用了本机被闲置的 Quadro P620 4GB(装 cu126 torch 后可用)
73
+ • 数值验证通过(top-1 与 CPU 一致)
74
+ • 诚实结论: P620 + eager torch = 10.9 tok/s < 自研 AVX2 CPU 内核 12.6 tok/s
75
+ (Pascal 算力弱 + 250 内核发射/token 的 eager 开销吞掉带宽优势)
76
+ • 这反而证明: 自研 CPU 内核已把这台机器推到 GPU 难以企及的效率
77
+ ```
78
+
79
+ ### 🍃 v0.8 颠覆点:性能/瓦特治理(行业忽视的维度)
80
+
81
+ **实测颠覆**:decode 带宽受限负载下,**2 线程跑出与 16 线程相同的速度**,
82
+ 而 16 线程多烧 CPU 时间(发热/风扇)只为心理安慰——这是所有默认全核的
83
+ 推理框架(含 Ollama)都在犯的错。
84
+
85
+ ```
86
+ Qwen2.5-0.5B 实测(60 token 贪心):
87
+ 档位 线程 tok/s CPU秒/token 风扇
88
+ turbo 16 9.44 0.2500 轰鸣
89
+ whisper 2 9.60 0.2357 几乎不转 <- 同速、更省电、更安静
90
+ ```
91
+
92
+ ```python
93
+ m = acorn.load("qwen.acorn", tokenizer_path=..., eco="whisper")
94
+ # whisper = 2 线程 + race-to-idle 间隙 + 低进程优先级(静音)
95
+ # balanced = 4 线程(速度甜点); turbo = 全核(默认)
96
+ ```
97
+
98
+ ### 🌌 v0.7 终极验证:Qwen3-8B 上机
99
+
100
+ ```
101
+ 16.5GB RAM / 无 GPU 的机器,加载并运行 8B 模型(PyTorch 在此机器直接 OOM)
102
+
103
+ ┌────────────────────────────────────────────────────────────┐
104
+ │ 转换: 5 分片 bf16 (16.4GB) --流式(RAM峰值<1GB)--> 4.10GB INT4 │
105
+ │ 加载: 77.6s | 常驻 4.10GB(fp32 等价 16.4GB → 内存 ÷16) │
106
+ │ 速度: 1.7-2.2 tok/s(纯 CPU decode) │
107
+ ├────────────────────────────────────────────────────────────┤
108
+ │ "用一句话解释量子纠缠" -> "首先,我需要确保自己正确理解…" │
109
+ │ (Qwen3 思维链被正确激活) │
110
+ │ "check if a number is prime" -> 推理式英文回答 │
111
+ │ 数学链 3+3=6, 4+4=8, 5+5=10 … 全对 │
112
+ └────────────────────────────────────────────────────────────┘
113
+ ```
114
+
115
+ > `python examples/run_qwen3.py`。架构支持:Qwen3 QK-Norm(数值 vs 独立参考
116
+ > 实现 rel=3.8e-7)+ 多分片 safetensors 流式转换(`acorn.shard`)。
117
+
118
+ ### ⚡ v0.6 破壁:投机解码 + 聪明度修正
119
+
120
+ ```
121
+ 投机解码 (Prompt-Lookup Decoding) —— 打破自回归串行墙:
122
+ 一次前向验证 K 个草稿 token, 接受率 1.8-2.3, 实测加速 1.3-1.7x
123
+ 金标准验证: 贪心投机输出与常规解码逐字一致(数学保证 + 实测确认)
124
+
125
+ 聪明度三件套 (Instruct 模型的正确打开方式):
126
+ ChatML/Llama3 模板 + 重复惩罚 + 停止序列 -> 裸续写 -> 真正的对话质量
127
+
128
+ fibonacci 任务: 10.8 -> 18.3 tok/s (x1.70)
129
+ Q&A 模式任务 : 13.0 -> 21.5 tok/s (x1.65)
130
+ ```
131
+
132
+ ```python
133
+ text, stats = m.generate_chat(
134
+ "Write a Python function", # 自动 ChatML 模板
135
+ max_tokens=128,
136
+ temperature=0.7, repetition=1.15, # 重复惩罚
137
+ speculative=True, # 投机解码 (贪心验证)
138
+ )
139
+ ```
140
+
141
+ ### 📊 全维度实测数据(examples/benchmark_report.py)
142
+
143
+ | 维度 | 基线 | Acorn | 倍数 |
144
+ |---|---|---|---|
145
+ | 8B 权重体积 | 16.4 GB bf16 | **4.10 GB INT4** | **÷4** |
146
+ | 8B 常驻内存 | 16.4 GB+(本机 OOM) | **4.10 GB** | **÷16**(vs fp32) |
147
+ | 8B 转换 RAM 峰值 | 32 GB+(常规 OOM) | **<1 GB**(流式) | 16GB 机器转 8B |
148
+ | GEMV 4096×11008 | 12.3 ms fp32 BLAS | **1.95 ms** int4 内核 | **快 6.3×** |
149
+ | KV Cache(ctx2048×36层) | 0.60 GB fp32 | **0.15 GB** int8 | **÷4**(偏差0.4%) |
150
+ | 0.5B 投机 decode | 9.7 tok/s | **12.8-21.5 tok/s** | **快 1.3-1.65×** |
151
+ | 同预算量化质量 | 统一 INT4 KL=0.00104 | **AutoBit KL=0.00014** | **↓87%** |
152
+ | 训练吞吐(CPU 参考) | — | **3284 tok/s** | — |
153
+
154
+ ### 🏆 v0.5 王牌验证:真实 AI 模型在 Acorn 上运行
155
+
156
+ ```
157
+ Qwen2.5-0.5B-Instruct (阿里通义, Apache-2.0, 0.49B 参数)
158
+ ┌──────────────────────────────────────────────────────────────┐
159
+ │ 原始 : 988 MB bf16 (safetensors) │
160
+ │ Acorn : 249 MB INT4 (25%) + KV int8 │
161
+ │ 生成速度 : 10+ tok/s │
162
+ │ 依赖 : transformers/torch/llama.cpp = 0 (全部自研) │
163
+ ├──────────────────────────────────────────────────────────────┤
164
+ │ "The capital of France is" -> " located in which of the..." │
165
+ │ "人工智能的未来" -> "是什么?2020年,人工智能..." │
166
+ │ "def hello_world():" -> " print(\"I'm so very..." │
167
+ └──────────────────────────────────────────────────────────────┘
168
+ ```
169
+
170
+ > `python examples/run_qwen.py` 一键复现。链路上每一环——safetensors 读取、
171
+ > LLaMA 前向、BPE 分词、INT4 量化、AVX2 内核、KV int8、采样——都是 Acorn 自己实现的。
172
+
173
+ ### v0.4 实测(真实 7B 规格,非玩具模型)
174
+
175
+ ```
176
+ ┌─ LLaMA-7B 规格 (L=32, d=4096, H=32, KV=8, FFN=11008, V=32000) ─────┐
177
+ │ int4 常驻内存 : 2.91 GB (fp32 等价 23.2 GB, 压缩 7.98x) │
178
+ │ decode 吞吐 : 4.7 tok/s (18.6 GB/s 有效带宽 = 机器上限 72%) │
179
+ │ 层流式常驻 : 154 MB (省 19x, 磁盘 IO 代价 5.9x) │
180
+ │ AutoBit 同预算: KL 0.000138 vs 统一 INT4 的 0.001036 (↓87%) │
181
+ │ 数值正确性 : 与独立参考实现 rel=1.5e-7 │
182
+ └─────────────────────────────────────────────────────────────────────┘
183
+ ```
184
+
185
+ > 数据来自 `examples/bench_llama7b.py` / `bench_stream.py`,真实运行输出。
186
+ > **关于物理极限**:decode 是带宽受限任务,本机内存带宽上限 ~26 GB/s(实测
187
+ > memcpy),我们达到 18.6 GB/s = 72%。要再快只有两条路:**读更少的字节**
188
+ > (AutoBit/稀疏化)或**换更强的内存**(GPU/更快的 DDR)。
189
+
190
+ ## 30 秒上手
191
+
192
+ ```bash
193
+ python examples/hello_acorn.py # 全链路:训练→量化→流式生成→bench→LoRA
194
+ ```
195
+
196
+ ```python
197
+ import acorn
198
+
199
+ model = acorn.train(steps=200) # 1. 训练(RoPE + warmup/cosine)
200
+ acorn.pack(model, "mymodel.acorn") # 2. INT4 量化打包(全模型 6.4x)
201
+ model = acorn.load("mymodel.acorn") # 3. 加载
202
+ for tok in model.generate_stream("Acorn: ", 90, top_p=0.95):
203
+ print(tok, end="") # 4. 流式生成(KV Cache)
204
+ ```
205
+
206
+ CLI 也是一等公民:
207
+
208
+ ```bash
209
+ python -m acorn train --steps 200 --out hello.acorn
210
+ python -m acorn run --model hello.acorn --prompt "Acorn: " --stream
211
+ python -m acorn bench --model hello.acorn
212
+ python -m acorn lora --model hello.acorn --corpus my.txt --steps 150
213
+ ```
214
+
215
+ ### 原生内核(可选,零依赖仍可运行)
216
+
217
+ 有 gcc/cl 时自动编译并缓存内核(AVX2 + 常驻线程池);没有编译器则自动回退
218
+ NumPy 路径,**功能完全一致,只是慢一些**:
219
+
220
+ ```python
221
+ from acorn import _kernels as K
222
+ K.info() # {'native': True, 'avx2': True, 'threads': 16, 'compiler': '...'}
223
+ ```
224
+
225
+ 内核做三件事:**① 在线解包 int4**(不物化权重)**② SIMD FMA 点积** ③ **常驻线程池**。
226
+
227
+ ## 仓库结构
228
+
229
+ ```
230
+ acorn-framework/
231
+ ├── PLAN.md # 🗺️ 总体项目计划(愿景/里程碑/风险)
232
+ ├── RUNTIME_PLAN.md # ⚙️ 运行模型的详细计划(格式/内存/量化/API)
233
+ ├── assets/ # Logo 资产
234
+ │ ├── logo.svg # 主 logo(≥32px 场景,全细节版)
235
+ │ ├── logo_favicon.svg # 16–24px 简化版(无闪电、亮黄茎)
236
+ │ ├── logo_dark.svg # 深色背景版(提亮帽体/茎)
237
+ │ └── logo_wordmark.svg # 横版字标(图形 + ACORN + 口号)
238
+ ├── acorn/ # 框架核心(零第三方依赖)
239
+ │ ├── _kernels/ # 原生内核后端(可选,可自动编译)
240
+ │ │ ├── acorn_int4.c # AVX2 int4 在线解包 + FMA 点积 + 线程池
241
+ │ │ └── __init__.py # 自动编译/探测/ctypes 绑定/NumPy 回退
242
+ │ ├── _ops.py # 零依赖张量算子(NumPy 加速 + 纯 Python 回退)
243
+ │ ├── _autograd.py # 微型自动微分引擎(requires_grad 冻结机制)
244
+ │ ├── model.py # TinyGPT(RMSNorm/RoPE/MHA/MLP + KV Cache 前向)
245
+ │ ├── train.py # 训练引擎(AdamW/梯度裁剪/warmup+cosine)
246
+ │ ├── pack.py # INT4 逐通道量化 + .acorn 容器格式
247
+ │ ├── runtime.py # 运行时(加载/流式生成/top-p/KV Cache 主循环)
248
+ │ ├── lora.py # LoRA:冻结基座 + 低秩适配器 + merge
249
+ │ ├── bench.py # 性能基准(prefill/decode/缓存收益)
250
+ │ └── __main__.py # CLI(train/run/bench/lora)
251
+ ├── examples/
252
+ │ ├── hello_acorn.py # 全链路演示(训练→量化→流式→bench→LoRA→merge)
253
+ │ └── bench_7b.py # 7B 规格实测(内存占用 + decode 吞吐)
254
+ └── tests/ # 26 项自测(梯度对拍/KV一致性/LoRA/内核/CLI)
255
+ ```
256
+
257
+ ## 技术支柱
258
+
259
+ ```
260
+ ┌──────────────────────────────────────┐
261
+ │ SIZE · 更小 │
262
+ │ AutoBit 动态混合位宽 · INT4/3/2 │
263
+ │ 结构化剪枝 · 低秩权重共享 │
264
+ ├──────────────────────────────────────┤
265
+ │ SPEED · 更快 │
266
+ │ 层流式加载 · 分页 KV Cache │
267
+ │ 算子融合 · 稀疏注意力 · 可插拔内核 │
268
+ ├──────────────────────────────────────┤
269
+ │ SIMPLE · 更简单 │
270
+ │ 3 行推理 · 5 行训练 · 零依赖核心 │
271
+ │ 自动设备编排 (NVMe/RAM/VRAM) │
272
+ ├──────────────────────────────────────┤
273
+ │ SCALE · 更从容 │
274
+ │ QLoRA 轻训练 · CPU offload │
275
+ │ 弹性断点续训 · 声明式配置 │
276
+ └──────────────────────────────────────┘
277
+ ```
278
+
279
+ ## 路线图(摘要)
280
+
281
+ | 阶段 | 代号 | 目标 | 状态 |
282
+ |---|---|---|---|
283
+ | M0 | **Seed 种子** | 设计冻结 + 种子内核(训练/量化/生成全链路可跑) | ✅ 本仓库 |
284
+ | M1 | **Sprout 发芽** | 推理 MVP:7B 模型 INT4 在 8GB 内存无独显设备跑通 | 🔜 |
285
+ | M2 | **Grow 生长** | 训练 MVP:单张 12GB 消费级 GPU QLoRA 微调 7B | ⏳ |
286
+ | M3 | **Tree 成树** | 生态:模型 Hub、HF 一键转换、插件内核 | ⏳ |
287
+ | M4 | **Forest 成林** | 分布式训练、编译器级图优化 | ⏳ |
288
+
289
+ 详见 [PLAN.md](PLAN.md) 与 [RUNTIME_PLAN.md](RUNTIME_PLAN.md)。
290
+
291
+ ## 差异化定位(诚实版)
292
+
293
+ Acorn 不假装在所有维度都赢过成熟项目:
294
+
295
+ | | PyTorch | llama.cpp | vLLM | **Acorn** |
296
+ |---|---|---|---|---|
297
+ | 内核极致性能 | ✓ | ✓✓ | ✓✓ | 借力可插拔内核 |
298
+ | 小内存运行 | 部分 | ✓ | ✗ | ✓(核心目标) |
299
+ | 训推一体轻量化 | 训强推弱 | 推强训弱 | 仅推理 | ✓(核心目标) |
300
+ | 上手心智负担 | 高 | 中 | 中 | **3 行代码**(核心目标) |
301
+ | 动态混合位宽量化 | 插件 | 手动 | ✗ | ✓ AutoBit(核心目标) |
302
+
303
+ 策略:**不重造轮子,做统一编排层**——自有模型格式 + 自动量化 + 内存编排 + 极简 API,内核可插拔(NumPy 参考内核 → 未来适配 llama.cpp/自研内核)。
304
+
305
+ ## License
306
+
307
+ MIT
@@ -0,0 +1,279 @@
1
+ <div align="center">
2
+
3
+ <img src="assets/logo.svg" width="160" alt="Acorn Framework Logo"/>
4
+
5
+ # Acorn Framework 🌰
6
+
7
+ **Big models. Tiny footprint. —— 芥子纳须弥,把大模型装进口口袋。**
8
+
9
+ *以小搏大的 AI 运行与训练框架:更小的空间 · 更快的速度 · 更少的痛苦*
10
+
11
+ ![status](https://img.shields.io/badge/status-v0.3--native--kernel-green) ![deps](https://img.shields.io/badge/core%20deps-0-blue) ![python](https://img.shields.io/badge/python-3.9%2B-blue) ![license](https://img.shields.io/badge/license-MIT-black)
12
+
13
+ </div>
14
+
15
+ ---
16
+
17
+ ## 为什么是 Acorn?
18
+
19
+ 模型越来越大,设备没有变大。7B 参数的模型以 FP16 存储要 **14 GB**,而世界上绝大多数设备只有 8–16 GB 内存。
20
+
21
+ Acorn 的信念:**推理和训练不应该被显存大小判处死刑。**
22
+
23
+ | 痛点 | Acorn 的回答 | 实测 |
24
+ |---|---|---|
25
+ | 模型放不进显存 | **int4 压缩态常驻**(0.5 B/参数,绝不物化 fp 矩阵)+ **层流式** | 7B = **2.91 GB**;流式 **154 MB**(省 19x) |
26
+ | 推理太慢 | **原生 AVX2 内核** + 常驻线程池 + RoPE + KV Cache + 投影融合 | 7B decode **4.7 tok/s**(带宽已到机器上限 72%) |
27
+ | 量化掉精度 | **AutoBit**:逐层敏感度实测(跨度 10⁵×)→ 字节预算下自动混合位宽 | 同预算 KL **↓87%** |
28
+ | 长上下文吃内存 | **KV Cache int8**(逐 token absmax 量化) | 内存 **28%**,输出偏差 0.4% |
29
+ | 模型太大 | **结构化剪枝 + 稀疏内核**(FFN 神经元幅度剪枝 + 位图跳零) | 50% 剪枝:字节 50%,**加速 x5.8**,loss 仅 x1.08 |
30
+ | 接不了真模型 | **safetensors 零依赖读写 + LLaMA 架构 + BPE 分词器 + 流式转换器** | 数值与独立参考实现一致(rel 1.5e-7) |
31
+ | 框架太重 | **零依赖核心**(NumPy 可选加速),纯 Python 也能跑全链路 | 0 依赖 |
32
+ | 训练门槛高 | **LoRA**:冻结基座只训适配器,合并后可直接打包 | 25.3% 参数学新语料 |
33
+ | API 记不住 | **3 行代码跑模型**,流式输出、top-k/top-p 开箱即用 | — |
34
+
35
+ ### 🖥️ v0.9:聊天室 UI + GPU 后端
36
+
37
+ ```
38
+ 交互式聊天(examples/chat.py):
39
+ • 思考流: [thinking...] 深灰显示思考 → [think done] → 正文
40
+ • 终端 Markdown 渲染(粗体/代码块/标题/列表, 零依赖 ANSI)
41
+ • 多轮对话跨轮 KV 复用 · /eco /spec /raw 命令
42
+
43
+ GPU 后端(acorn.gpu, torch CUDA):
44
+ • 发现并启用了本机被闲置的 Quadro P620 4GB(装 cu126 torch 后可用)
45
+ • 数值验证通过(top-1 与 CPU 一致)
46
+ • 诚实结论: P620 + eager torch = 10.9 tok/s < 自研 AVX2 CPU 内核 12.6 tok/s
47
+ (Pascal 算力弱 + 250 内核发射/token 的 eager 开销吞掉带宽优势)
48
+ • 这反而证明: 自研 CPU 内核已把这台机器推到 GPU 难以企及的效率
49
+ ```
50
+
51
+ ### 🍃 v0.8 颠覆点:性能/瓦特治理(行业忽视的维度)
52
+
53
+ **实测颠覆**:decode 带宽受限负载下,**2 线程跑出与 16 线程相同的速度**,
54
+ 而 16 线程多烧 CPU 时间(发热/风扇)只为心理安慰——这是所有默认全核的
55
+ 推理框架(含 Ollama)都在犯的错。
56
+
57
+ ```
58
+ Qwen2.5-0.5B 实测(60 token 贪心):
59
+ 档位 线程 tok/s CPU秒/token 风扇
60
+ turbo 16 9.44 0.2500 轰鸣
61
+ whisper 2 9.60 0.2357 几乎不转 <- 同速、更省电、更安静
62
+ ```
63
+
64
+ ```python
65
+ m = acorn.load("qwen.acorn", tokenizer_path=..., eco="whisper")
66
+ # whisper = 2 线程 + race-to-idle 间隙 + 低进程优先级(静音)
67
+ # balanced = 4 线程(速度甜点); turbo = 全核(默认)
68
+ ```
69
+
70
+ ### 🌌 v0.7 终极验证:Qwen3-8B 上机
71
+
72
+ ```
73
+ 16.5GB RAM / 无 GPU 的机器,加载并运行 8B 模型(PyTorch 在此机器直接 OOM)
74
+
75
+ ┌────────────────────────────────────────────────────────────┐
76
+ │ 转换: 5 分片 bf16 (16.4GB) --流式(RAM峰值<1GB)--> 4.10GB INT4 │
77
+ │ 加载: 77.6s | 常驻 4.10GB(fp32 等价 16.4GB → 内存 ÷16) │
78
+ │ 速度: 1.7-2.2 tok/s(纯 CPU decode) │
79
+ ├────────────────────────────────────────────────────────────┤
80
+ │ "用一句话解释量子纠缠" -> "首先,我需要确保自己正确理解…" │
81
+ │ (Qwen3 思维链被正确激活) │
82
+ │ "check if a number is prime" -> 推理式英文回答 │
83
+ │ 数学链 3+3=6, 4+4=8, 5+5=10 … 全对 │
84
+ └────────────────────────────────────────────────────────────┘
85
+ ```
86
+
87
+ > `python examples/run_qwen3.py`。架构支持:Qwen3 QK-Norm(数值 vs 独立参考
88
+ > 实现 rel=3.8e-7)+ 多分片 safetensors 流式转换(`acorn.shard`)。
89
+
90
+ ### ⚡ v0.6 破壁:投机解码 + 聪明度修正
91
+
92
+ ```
93
+ 投机解码 (Prompt-Lookup Decoding) —— 打破自回归串行墙:
94
+ 一次前向验证 K 个草稿 token, 接受率 1.8-2.3, 实测加速 1.3-1.7x
95
+ 金标准验证: 贪心投机输出与常规解码逐字一致(数学保证 + 实测确认)
96
+
97
+ 聪明度三件套 (Instruct 模型的正确打开方式):
98
+ ChatML/Llama3 模板 + 重复惩罚 + 停止序列 -> 裸续写 -> 真正的对话质量
99
+
100
+ fibonacci 任务: 10.8 -> 18.3 tok/s (x1.70)
101
+ Q&A 模式任务 : 13.0 -> 21.5 tok/s (x1.65)
102
+ ```
103
+
104
+ ```python
105
+ text, stats = m.generate_chat(
106
+ "Write a Python function", # 自动 ChatML 模板
107
+ max_tokens=128,
108
+ temperature=0.7, repetition=1.15, # 重复惩罚
109
+ speculative=True, # 投机解码 (贪心验证)
110
+ )
111
+ ```
112
+
113
+ ### 📊 全维度实测数据(examples/benchmark_report.py)
114
+
115
+ | 维度 | 基线 | Acorn | 倍数 |
116
+ |---|---|---|---|
117
+ | 8B 权重体积 | 16.4 GB bf16 | **4.10 GB INT4** | **÷4** |
118
+ | 8B 常驻内存 | 16.4 GB+(本机 OOM) | **4.10 GB** | **÷16**(vs fp32) |
119
+ | 8B 转换 RAM 峰值 | 32 GB+(常规 OOM) | **<1 GB**(流式) | 16GB 机器转 8B |
120
+ | GEMV 4096×11008 | 12.3 ms fp32 BLAS | **1.95 ms** int4 内核 | **快 6.3×** |
121
+ | KV Cache(ctx2048×36层) | 0.60 GB fp32 | **0.15 GB** int8 | **÷4**(偏差0.4%) |
122
+ | 0.5B 投机 decode | 9.7 tok/s | **12.8-21.5 tok/s** | **快 1.3-1.65×** |
123
+ | 同预算量化质量 | 统一 INT4 KL=0.00104 | **AutoBit KL=0.00014** | **↓87%** |
124
+ | 训练吞吐(CPU 参考) | — | **3284 tok/s** | — |
125
+
126
+ ### 🏆 v0.5 王牌验证:真实 AI 模型在 Acorn 上运行
127
+
128
+ ```
129
+ Qwen2.5-0.5B-Instruct (阿里通义, Apache-2.0, 0.49B 参数)
130
+ ┌──────────────────────────────────────────────────────────────┐
131
+ │ 原始 : 988 MB bf16 (safetensors) │
132
+ │ Acorn : 249 MB INT4 (25%) + KV int8 │
133
+ │ 生成速度 : 10+ tok/s │
134
+ │ 依赖 : transformers/torch/llama.cpp = 0 (全部自研) │
135
+ ├──────────────────────────────────────────────────────────────┤
136
+ │ "The capital of France is" -> " located in which of the..." │
137
+ │ "人工智能的未来" -> "是什么?2020年,人工智能..." │
138
+ │ "def hello_world():" -> " print(\"I'm so very..." │
139
+ └──────────────────────────────────────────────────────────────┘
140
+ ```
141
+
142
+ > `python examples/run_qwen.py` 一键复现。链路上每一环——safetensors 读取、
143
+ > LLaMA 前向、BPE 分词、INT4 量化、AVX2 内核、KV int8、采样——都是 Acorn 自己实现的。
144
+
145
+ ### v0.4 实测(真实 7B 规格,非玩具模型)
146
+
147
+ ```
148
+ ┌─ LLaMA-7B 规格 (L=32, d=4096, H=32, KV=8, FFN=11008, V=32000) ─────┐
149
+ │ int4 常驻内存 : 2.91 GB (fp32 等价 23.2 GB, 压缩 7.98x) │
150
+ │ decode 吞吐 : 4.7 tok/s (18.6 GB/s 有效带宽 = 机器上限 72%) │
151
+ │ 层流式常驻 : 154 MB (省 19x, 磁盘 IO 代价 5.9x) │
152
+ │ AutoBit 同预算: KL 0.000138 vs 统一 INT4 的 0.001036 (↓87%) │
153
+ │ 数值正确性 : 与独立参考实现 rel=1.5e-7 │
154
+ └─────────────────────────────────────────────────────────────────────┘
155
+ ```
156
+
157
+ > 数据来自 `examples/bench_llama7b.py` / `bench_stream.py`,真实运行输出。
158
+ > **关于物理极限**:decode 是带宽受限任务,本机内存带宽上限 ~26 GB/s(实测
159
+ > memcpy),我们达到 18.6 GB/s = 72%。要再快只有两条路:**读更少的字节**
160
+ > (AutoBit/稀疏化)或**换更强的内存**(GPU/更快的 DDR)。
161
+
162
+ ## 30 秒上手
163
+
164
+ ```bash
165
+ python examples/hello_acorn.py # 全链路:训练→量化→流式生成→bench→LoRA
166
+ ```
167
+
168
+ ```python
169
+ import acorn
170
+
171
+ model = acorn.train(steps=200) # 1. 训练(RoPE + warmup/cosine)
172
+ acorn.pack(model, "mymodel.acorn") # 2. INT4 量化打包(全模型 6.4x)
173
+ model = acorn.load("mymodel.acorn") # 3. 加载
174
+ for tok in model.generate_stream("Acorn: ", 90, top_p=0.95):
175
+ print(tok, end="") # 4. 流式生成(KV Cache)
176
+ ```
177
+
178
+ CLI 也是一等公民:
179
+
180
+ ```bash
181
+ python -m acorn train --steps 200 --out hello.acorn
182
+ python -m acorn run --model hello.acorn --prompt "Acorn: " --stream
183
+ python -m acorn bench --model hello.acorn
184
+ python -m acorn lora --model hello.acorn --corpus my.txt --steps 150
185
+ ```
186
+
187
+ ### 原生内核(可选,零依赖仍可运行)
188
+
189
+ 有 gcc/cl 时自动编译并缓存内核(AVX2 + 常驻线程池);没有编译器则自动回退
190
+ NumPy 路径,**功能完全一致,只是慢一些**:
191
+
192
+ ```python
193
+ from acorn import _kernels as K
194
+ K.info() # {'native': True, 'avx2': True, 'threads': 16, 'compiler': '...'}
195
+ ```
196
+
197
+ 内核做三件事:**① 在线解包 int4**(不物化权重)**② SIMD FMA 点积** ③ **常驻线程池**。
198
+
199
+ ## 仓库结构
200
+
201
+ ```
202
+ acorn-framework/
203
+ ├── PLAN.md # 🗺️ 总体项目计划(愿景/里程碑/风险)
204
+ ├── RUNTIME_PLAN.md # ⚙️ 运行模型的详细计划(格式/内存/量化/API)
205
+ ├── assets/ # Logo 资产
206
+ │ ├── logo.svg # 主 logo(≥32px 场景,全细节版)
207
+ │ ├── logo_favicon.svg # 16–24px 简化版(无闪电、亮黄茎)
208
+ │ ├── logo_dark.svg # 深色背景版(提亮帽体/茎)
209
+ │ └── logo_wordmark.svg # 横版字标(图形 + ACORN + 口号)
210
+ ├── acorn/ # 框架核心(零第三方依赖)
211
+ │ ├── _kernels/ # 原生内核后端(可选,可自动编译)
212
+ │ │ ├── acorn_int4.c # AVX2 int4 在线解包 + FMA 点积 + 线程池
213
+ │ │ └── __init__.py # 自动编译/探测/ctypes 绑定/NumPy 回退
214
+ │ ├── _ops.py # 零依赖张量算子(NumPy 加速 + 纯 Python 回退)
215
+ │ ├── _autograd.py # 微型自动微分引擎(requires_grad 冻结机制)
216
+ │ ├── model.py # TinyGPT(RMSNorm/RoPE/MHA/MLP + KV Cache 前向)
217
+ │ ├── train.py # 训练引擎(AdamW/梯度裁剪/warmup+cosine)
218
+ │ ├── pack.py # INT4 逐通道量化 + .acorn 容器格式
219
+ │ ├── runtime.py # 运行时(加载/流式生成/top-p/KV Cache 主循环)
220
+ │ ├── lora.py # LoRA:冻结基座 + 低秩适配器 + merge
221
+ │ ├── bench.py # 性能基准(prefill/decode/缓存收益)
222
+ │ └── __main__.py # CLI(train/run/bench/lora)
223
+ ├── examples/
224
+ │ ├── hello_acorn.py # 全链路演示(训练→量化→流式→bench→LoRA→merge)
225
+ │ └── bench_7b.py # 7B 规格实测(内存占用 + decode 吞吐)
226
+ └── tests/ # 26 项自测(梯度对拍/KV一致性/LoRA/内核/CLI)
227
+ ```
228
+
229
+ ## 技术支柱
230
+
231
+ ```
232
+ ┌──────────────────────────────────────┐
233
+ │ SIZE · 更小 │
234
+ │ AutoBit 动态混合位宽 · INT4/3/2 │
235
+ │ 结构化剪枝 · 低秩权重共享 │
236
+ ├──────────────────────────────────────┤
237
+ │ SPEED · 更快 │
238
+ │ 层流式加载 · 分页 KV Cache │
239
+ │ 算子融合 · 稀疏注意力 · 可插拔内核 │
240
+ ├──────────────────────────────────────┤
241
+ │ SIMPLE · 更简单 │
242
+ │ 3 行推理 · 5 行训练 · 零依赖核心 │
243
+ │ 自动设备编排 (NVMe/RAM/VRAM) │
244
+ ├──────────────────────────────────────┤
245
+ │ SCALE · 更从容 │
246
+ │ QLoRA 轻训练 · CPU offload │
247
+ │ 弹性断点续训 · 声明式配置 │
248
+ └──────────────────────────────────────┘
249
+ ```
250
+
251
+ ## 路线图(摘要)
252
+
253
+ | 阶段 | 代号 | 目标 | 状态 |
254
+ |---|---|---|---|
255
+ | M0 | **Seed 种子** | 设计冻结 + 种子内核(训练/量化/生成全链路可跑) | ✅ 本仓库 |
256
+ | M1 | **Sprout 发芽** | 推理 MVP:7B 模型 INT4 在 8GB 内存无独显设备跑通 | 🔜 |
257
+ | M2 | **Grow 生长** | 训练 MVP:单张 12GB 消费级 GPU QLoRA 微调 7B | ⏳ |
258
+ | M3 | **Tree 成树** | 生态:模型 Hub、HF 一键转换、插件内核 | ⏳ |
259
+ | M4 | **Forest 成林** | 分布式训练、编译器级图优化 | ⏳ |
260
+
261
+ 详见 [PLAN.md](PLAN.md) 与 [RUNTIME_PLAN.md](RUNTIME_PLAN.md)。
262
+
263
+ ## 差异化定位(诚实版)
264
+
265
+ Acorn 不假装在所有维度都赢过成熟项目:
266
+
267
+ | | PyTorch | llama.cpp | vLLM | **Acorn** |
268
+ |---|---|---|---|---|
269
+ | 内核极致性能 | ✓ | ✓✓ | ✓✓ | 借力可插拔内核 |
270
+ | 小内存运行 | 部分 | ✓ | ✗ | ✓(核心目标) |
271
+ | 训推一体轻量化 | 训强推弱 | 推强训弱 | 仅推理 | ✓(核心目标) |
272
+ | 上手心智负担 | 高 | 中 | 中 | **3 行代码**(核心目标) |
273
+ | 动态混合位宽量化 | 插件 | 手动 | ✗ | ✓ AutoBit(核心目标) |
274
+
275
+ 策略:**不重造轮子,做统一编排层**——自有模型格式 + 自动量化 + 内存编排 + 极简 API,内核可插拔(NumPy 参考内核 → 未来适配 llama.cpp/自研内核)。
276
+
277
+ ## License
278
+
279
+ MIT
@@ -0,0 +1,53 @@
1
+ """
2
+ acorn — Big models. Tiny footprint. 芥子纳须弥。
3
+ ==================================================
4
+ 以小搏大的 AI 运行与训练框架。
5
+
6
+ 三行核心 API:
7
+ model = acorn.train(steps=200) # 训练
8
+ acorn.pack(model, "m.acorn") # INT4 量化打包
9
+ model = acorn.load("m.acorn") # 加载 -> generate / generate_stream
10
+
11
+ v0.7: Qwen3-8B 上机 (QK-Norm 架构 + 多分片流式转换, 16GB RAM 跑 8B)
12
+ v0.6: 投机解码 (Prompt-Lookup, 1.3-1.7x, 金标准验证) / Chat 模板+重复惩罚+停止序列
13
+ v0.5: 真实模型端到端 (Qwen2.5-0.5B 实跑) / KV Cache int8 / 结构化剪枝+稀疏内核 /
14
+ Qwen QKV-bias 支持
15
+ v0.4: 真实模型接入 (safetensors/转换器/LLaMA 架构/BPE) / AutoBit 混合位宽 /
16
+ 层流式加载 (常驻省 19x)
17
+ v0.3: 原生 int4 内核 (AVX2 + 常驻线程池) / 压缩态常驻 (0.5B/参数) / 嵌入表 gather
18
+ v0.2: RoPE / KV Cache / 流式生成 / top-p / LoRA / 梯度裁剪 / 余弦调度 / CLI / bench
19
+
20
+ python -m acorn train|run|bench|lora --help
21
+
22
+ 计划: PLAN.md / RUNTIME_PLAN.md
23
+ """
24
+ from __future__ import annotations
25
+
26
+ __version__ = "0.9.2"
27
+
28
+ from . import _ops as _ops # noqa: F401 (内部)
29
+ from .model import TinyGPT, TinyGPTConfig
30
+ from .train import train, AdamW
31
+ from .pack import pack_model, quantize_int4_channelwise, dequantize_int4
32
+ from .runtime import AcornModel, load, to_trainable
33
+ from . import lora # noqa: F401 (acorn.lora.inject_lora / merge_lora / stats)
34
+ from .bench import bench # noqa: F401
35
+ from . import autobit # noqa: F401 (acorn.autobit 敏感度/位宽计划)
36
+ from . import llama as llama_mod # noqa: F401 (acorn.llama 真实模型转换)
37
+ from . import tokenizer as tokenizer_mod # noqa: F401 (BPE 分词器)
38
+
39
+
40
+ def pack(model, path: str, verbose: bool = True) -> dict:
41
+ """量化打包模型到 .acorn 文件(train/pack/load 三件套之二)。"""
42
+ return pack_model(model, path, verbose=verbose)
43
+
44
+
45
+ __all__ = [
46
+ "TinyGPT", "TinyGPTConfig",
47
+ "train", "AdamW",
48
+ "pack", "pack_model",
49
+ "quantize_int4_channelwise", "dequantize_int4",
50
+ "AcornModel", "load", "to_trainable",
51
+ "lora", "bench", "autobit", "llama_mod", "tokenizer_mod",
52
+ "__version__",
53
+ ]