两人团队从零训练1B参数LLM:AQ项目复现与部署全指南
2026/9/20 0:33:00 网站建设 项目流程

这次我们来看一个很有意思的开源 LLM 项目:AQ。它由印度的一个两人团队从零训练,规模是 1B 参数,定位是“学术型 LLM”,发布入口是 Hacker News 的 Show HN。直白一点说,这不是基于 Llama、Mistral 的二次微调,而是自己造数据、自己搭训练流程、自己从权重开始训出来的一个 1B 模型。

这种项目在当下的 LLM 生态里值得单独关注。原因很简单:现在大部分团队做的都是“拿开源基座 + 领域数据微调”,真正从零训练一个小参数模型的公开案例并不多。尤其是两个人、1B 规模、学术目的这三个标签叠在一起,意味着它的训练流程、数据配比、Tokenization 设计、对齐策略可能比“模型本身跑分”更有参考价值。

这篇文章我会分几块来展开:先把这个项目的核心能力、门槛和使用边界讲清楚,再给出一套从环境准备、训练复现到本地推理验证的完整思路。因为项目是公开开源项目,实际训练脚本和配置要以仓库为准,但下面这套流程可以当作通用的 1B 模型复现和部署测试框架来用。

1. 核心能力速览

能力项说明
模型规模1B 参数,属于小参数 LLM,适合资源有限的团队和个人研究
项目类型从零训练(from-scratch)的学术型 LLM,非微调衍生模型
团队来源印度两人团队,发布渠道为 Show HN
训练方式自建数据管线 + 自建训练流程,具体数据量和 Token 数需看仓库说明
适用硬件1B 模型推理门槛较低,消费级 GPU 或高内存 CPU 均可尝试
显存占用需按推理框架和精度实测,1B 模型在 FP16 下通常占用较低
启动方式命令行推理脚本 / 可选 WebUI / 可选 API 服务
是否支持 API按项目仓库说明,可自行封装
是否支持批量任务可通过脚本批量加载文本测试,无内置队列时自行实现
适合场景学术研究、LLM 训练流程学习、小规模文本生成实验、教学演示

从项目标题能确定的硬信息就是:1B 参数、from-scratch、两人团队、学术定位。更细的数据集规模、训练时长、评测指标,必须等项目 README 或模型卡完全公开后才能确认。所以这里我不会写“训练了 3T Token”“跑了 1000 张 A100”这类没有依据的内容。

2. 适用场景与使用边界

AQ 适合哪类人?我梳理下来大概是这四类:

第一类,LLM 训练流程学习者和研究者。如果你想搞懂一个 1B 模型到底要经过哪些阶段——数据清洗、分词器训练、预训练、SFT、对齐评测,AQ 这种小型从零训练项目是最直观的参考样本。第二类,资源有限的个人开发者和高校实验室。1B 这个体量意味着哪怕只有一块消费级显卡,也有机会做推理和轻量微调实验。第三类,需要离线或私有化小模型做文本生成的工程团队。1B 模型在文本生成质量上肯定不如 7B、13B,但在延迟敏感、硬件受限、数据不能出内网的场景里,它有实用价值。第四类,做 RAG / Agent 任务编排的开发者。小模型跑不快,但作为工具调用、意图分类这类子任务,1B 模型可以成为一个低成本选项。

使用边界也要说清楚:

  • 学术型 1B 模型的语言能力、推理能力、指令遵循能力有限,不适合做高难度的内容生成和复杂对话。
  • 从零训练的数据版权和授权问题需要单独确认,复现时要检查数据来源。
  • 如果只是做应用开发,直接拿这个模型推理即可;如果是为了复现训练,需要准备好充足的 GPU 算力和稳定的数据管线。
  • 涉及内部业务数据、个人隐私、人脸肖像、声音等敏感信息时,必须确认训练和使用授权,并在隔离环境验证。

3. 环境准备与前置条件

不管你是要复现 AQ 的训练流程,还是只把训练好的权重拿来推理,环境准备都建议按下面这套来检查。

3.1 操作系统与语言环境

从零训练 1B 模型,最常见的技术栈是 Linux + Python + PyTorch。Windows 也能跑推理,但训练流程建议直接用 Linux 服务器或 WSL2。Python 版本建议 3.10 或 3.11,新版 PyTorch 对这两个版本的支持最稳。

# 查看系统信息 uname -a python3 --version nvidia-smi

3.2 GPU 与显存评估

1B 模型显存估算可以用一个简单公式:参数量 × 精度字节数。FP16 下大约 2GB 权重,BF16 同样约 2GB,再加上优化器状态、激活值、KV Cache,推理一般 4GB 到 8GB 显存就能跑;训练则要看是否用 LoRA、是否用 DeepSpeed、是否开梯度检查点。具体数字以项目训练配置和本机实测为准,不建议网上看一个显存数字就直接照抄。

如果本机没有 NVIDIA GPU,也可以考虑纯 CPU 推理,速度会慢,但至少能验证模型能否输出。

3.3 Python 虚拟环境与依赖

强烈建议用虚拟环境隔离依赖,不要直接装在系统 Python 里。常见依赖包括 PyTorch、Transformers、Tokenizers、Accelerate、DeepSpeed、Datasets、Hugging Face Hub 等。

python3 -m venv venv source venv/bin/activate pip install --upgrade pip pip install torch transformers tokenizers accelerate datasets

训练场景再按需安装:

pip install deepspeed wandb tensorboard

3.4 磁盘空间

1B 模型的 checkpoint 通常在 2GB 到 10GB 之间,取决于保存精度和是否包含优化器状态。如果完整复现训练,原始数据集、预处理后的 Token 缓存、日志和中间 checkpoint 建议预留 100GB 以上可用空间。

3.5 端口与进程检查

如果后面要启动 WebUI 或 API 服务,先检查端口是否被占用。

lsof -i :7860 lsof -i :8000

被占用就换端口,或者直接 kill 残留进程。这类问题在本地部署里非常常见。

4. 从零训练 1B LLM 的一般路径

AQ 的价值不只是模型权重,更是“从零训练”这个流程本身。即使我们拿不到无损训练日志,也可以按 LLM 训练的通用路线来复现和理解。

4.1 数据准备与清洗

从零训练的核心是数据。一个 1B 模型通常需要几十亿到几百亿 Token 才有基本语言能力,具体数量取决于模型设计目标和训练预算。数据来源包括开源文本语料、代码、论文摘要、教科书等,学术型 LLM 会更侧重高质量文本。

数据清洗一般做这几件事:去重、过滤低质量内容、去掉敏感和个人信息、统一格式、按比例混合不同来源。

# 数据预处理示例:统计 Token 长度分布 from transformers import AutoTokenizer from datasets import load_dataset tokenizer = AutoTokenizer.from_pretrained("path/to/aq-tokenizer") dataset = load_dataset("json", data_files="raw_data.jsonl", split="train") def tokenize_count(examples): return {"length": [len(tokenizer.encode(t)) for t in examples["text"]]} dataset = dataset.map(tokenize_count, batched=True, remove_columns=["text"]) print(dataset.to_pandas()["length"].describe())

这个脚本能帮你在预处理阶段先摸清语料的长度分布,再决定截断策略和打包方式。

4.2 分词器训练

1B 模型的分词器一般用 Byte-Level BPE。词表大小常见做法是 32K 到 128K,学术模型偏保守的话可能用 32K 或 64K。训练分词器用 Hugging Face Tokenizers 库最方便。

from tokenizers import ByteLevelBPETokenizer tokenizer = ByteLevelBPETokenizer() tokenizer.train(files=["corpus.txt"], vocab_size=32768, min_frequency=2, special_tokens=["<pad>", "<eos>", "<unk>"]) tokenizer.save_model("tokenizer_output")

注意:分词器词表大小直接影响模型 embedding 参数总量。1B 模型如果词表 128K,光 embedding 层就有 128K × 4096 约 5.24 亿参数,接近模型一半。这个比例要在模型设计阶段算清楚。

4.3 模型结构与训练配置

1B 模型一般沿用 LLaMA 风格的 decoder-only 结构。相比大模型,小模型要更注意训练稳定性,学习率、warmup、batch size 都要调。以下是一份可参考的配置模板,具体值需要按实际硬件调整:

{ "model": { "hidden_size": 2048, "intermediate_size": 5632, "num_hidden_layers": 24, "num_attention_heads": 16, "num_key_value_heads": 8, "vocab_size": 32768, "max_position_embeddings": 2048, "rms_norm_eps": 1e-6 }, "training": { "per_device_train_batch_size": 8, "gradient_accumulation_steps": 8, "learning_rate": 3e-4, "weight_decay": 0.1, "warmup_steps": 1000, "num_train_epochs": 1, "bf16": true, "gradient_checkpointing": true } }

关于精度,FP16、BF16、FP32 的选择直接影响显存占用和训练稳定性。1B 小模型用 BF16 比较稳妥——动态范围大,训练更稳定;FP16 在小模型上容易出现溢出问题。消费级显卡如果不支持 BF16,再考虑 FP16 加 loss scaling。

4.4 预训练启动示例

预训练代码可以直接用 Hugging Face Transformers 的 Trainer 或自定义 PyTorch 训练循环。下面是一段基于 Trainer 的简化启动示例:

from transformers import AutoConfig, AutoModelForCausalLM, Trainer, TrainingArguments from datasets import load_dataset config = AutoConfig.from_pretrained("config.json") model = AutoModelForCausalLM.from_config(config) dataset = load_dataset("json", data_files="tokenized_data.jsonl", split="train") training_args = TrainingArguments( output_dir="./aq-checkpoints", per_device_train_batch_size=8, gradient_accumulation_steps=8, learning_rate=3e-4, bf16=True, logging_steps=10, save_steps=500, save_total_limit=3, report_to="tensorboard", ) trainer = Trainer( model=model, args=training_args, train_dataset=dataset, ) trainer.train()

这里需要注意:如果你把数据集预先转成了 Token ID,并且每条样本长度相同,可以配置 DataCollator 直接拼接训练。实际项目中,tokenizer 的 pad 策略、eos 处理、多文档打包都要在数据管线里解决。

4.5 对齐与评测

从零预训练完成后,通常还要经过 SFT(监督微调)和对齐步骤,模型才更适合对话和指令任务。学术型项目可能更重视评测报告,所以会跑 MMLU、HellaSwag、ARC、HumanEval 等公开评测。

# 使用 lm-evaluation-harness 跑评测示例 pip install lm-evaluation-harness lm_eval --model hf \ --model_args pretrained=./aq-checkpoints/final \ --tasks hellaswag,arc_easy,arc_challenge \ --batch_size 8 \ --device cuda

这个评测工具是社区常用方案,跑通之后可以自己对比不同 checkpoint 的效果。

5. 本地部署与推理验证

训练是项目作者做的事情,我们拿到权重之后首先验证的是能不能顺利加载、能不能稳定输出。

5.1 下载模型与目录规划

建议按固定目录管理模型文件和测试脚本:

aq-llm/ ├── models/ │ └── aq-1b/ ├── tokenizer/ ├── scripts/ ├── inputs/ └── outputs/

如果模型权重托管在 Hugging Face,可以用snapshot_download下载:

from huggingface_hub import snapshot_download snapshot_download(repo_id="作者名/AQ-1B", local_dir="./models/aq-1b")

如果只有原始权重文件而没有 Hugging Face 格式,需要先转换成 Transformers 的config.jsonmodel.safetensorstokenizer.json格式,这一步取决于项目给出的权重格式。

5.2 基础推理脚本

写一个最简推理脚本,验证模型能加载、能续写:

from transformers import AutoModelForCausalLM, AutoTokenizer import torch model_path = "./models/aq-1b" tokenizer = AutoTokenizer.from_pretrained(model_path) model = AutoModelForCausalLM.from_pretrained(model_path, torch_dtype=torch.float16, device_map="auto") prompt = "Large language models are" inputs = tokenizer(prompt, return_tensors="pt").to(model.device) outputs = model.generate( **inputs, max_new_tokens=128, do_sample=True, temperature=0.7, top_p=0.9, ) print(tokenizer.decode(outputs[0], skip_special_tokens=True))

如果这一步跑不通,后面的 WebUI 和 API 都不用看,先排查模型路径、tokenizer 版本、CUDA 是否可用。

5.3 生成参数对结果的影响

1B 模型对采样参数比较敏感。实测时可重点对比:

  • temperature从 0.3 到 0.9 的变化,低温度输出更稳定但容易重复。
  • top_p从 0.8 到 1.0 的变化。
  • max_new_tokens的大小,1B 模型生成长文本时容易跑偏或重复,建议先控制在 128 到 256。
outputs = model.generate( **inputs, max_new_tokens=256, do_sample=True, temperature=0.5, top_p=0.85, repetition_penalty=1.1, )

repetition_penalty对 1B 模型很有用,小模型尤其容易出现整段重复的问题。

5.4 模型批量测试

要验证模型稳定性,可以准备一组覆盖不同领域的测试提示词,批处理跑一遍:

prompts = [ "Explain the concept of gravity in simple terms.", "Write a short story about a robot learning to paint.", "What are the main differences between TCP and UDP?", "Summarize the benefits of reading books.", ] results = [] for prompt in prompts: inputs = tokenizer(prompt, return_tensors="pt").to(model.device) outputs = model.generate(**inputs, max_new_tokens=128, do_sample=True, temperature=0.6, top_p=0.9) text = tokenizer.decode(outputs[0], skip_special_tokens=True) results.append({"prompt": prompt, "output": text}) for item in results: print("Prompt:", item["prompt"]) print("Output:", item["output"]) print("---")

这一步能快速暴露出模型的问题:答非所问、中英文混用、重复输出、特殊字符异常。把这些结果存成 JSON 或 Markdown,方便后面跟其他模型对比。

6. 接口 API 与批量任务接入

AQ 项目不一定自带 API 服务。如果仓库没有提供,我们可以用 FastAPI 直接封装一个,把上面的推理脚本变成一个可调用的 HTTP 接口,便于接到 RAG、Agent 或其他业务系统里。

6.1 最简 API 服务

from fastapi import FastAPI, Request from transformers import AutoModelForCausalLM, AutoTokenizer import torch app = FastAPI() model_path = "./models/aq-1b" tokenizer = AutoTokenizer.from_pretrained(model_path) model = AutoModelForCausalLM.from_pretrained(model_path, torch_dtype=torch.float16, device_map="auto") @app.post("/generate") async def generate(request: Request): data = await request.json() prompt = data.get("prompt", "") max_new_tokens = data.get("max_new_tokens", 128) temperature = data.get("temperature", 0.7) top_p = data.get("top_p", 0.9) inputs = tokenizer(prompt, return_tensors="pt").to(model.device) outputs = model.generate( **inputs, max_new_tokens=max_new_tokens, do_sample=True, temperature=temperature, top_p=top_p, ) text = tokenizer.decode(outputs[0], skip_special_tokens=True) return {"prompt": prompt, "output": text}

启动命令:

uvicorn api_server:app --host 127.0.0.1 --port 8000

注意:API 服务默认监听 127.0.0.1 即可,不要直接暴露到公网。如果要给局域网其他机器调用,再按需修改 host,同时加访问控制。

6.2 curl 调用示例

curl -X POST http://127.0.0.1:8000/generate \ -H "Content-Type: application/json" \ -d '{"prompt": "Write a Python function to compute factorial", "max_new_tokens": 128, "temperature": 0.5}'

6.3 Python 批量调用示例

有了 API,批量任务只需要在客户端循环发送请求:

import requests import json payloads = [ {"prompt": "Explain how exception handling works in Python.", "max_new_tokens": 128}, {"prompt": "What is the difference between lists and tuples in Python?", "max_new_tokens": 128}, {"prompt": "Write a short poem about a server room.", "max_new_tokens": 128}, ] results = [] for payload in payloads: resp = requests.post("http://127.0.0.1:8000/generate", json=payload, timeout=120) results.append(resp.json()) print(resp.json()["output"]) print("---") with open("outputs/batch_results.json", "w", encoding="utf-8") as f: json.dump(results, f, ensure_ascii=False, indent=2)

批量任务要加两个东西:一是异常重试,二是超时控制。不然某个 prompt 让模型陷入重复生成,整个批量任务会卡住。

for idx, payload in enumerate(payloads): for attempt in range(3): try: resp = requests.post("http://127.0.0.1:8000/generate", json=payload, timeout=120) resp.raise_for_status() results.append((idx, resp.json())) break except Exception as e: if attempt == 2: results.append((idx, {"error": str(e)})) else: time.sleep(2 ** attempt)

7. 资源占用与性能观察

从零训练的算力需求确实是门槛,但推理侧的观察我们完全可以自己测。

7.1 显存占用怎么看

nvidia-smi能看整体占用,但精确到进程更推荐:

nvidia-smi --query-gpu=memory.used,memory.total,utilization.gpu --format=csv -l 1

更细的 PyTorch 内存分析可以临时加一段代码:

print(torch.cuda.memory_summary(device=model.device))

7.2 显存和速度观察点

推理时重点看几个指标:

  • 模型加载后的基础显存占用。
  • 生成 128 Token 和 512 Token 时显存变化。
  • 批量输入 batch size 从 1 涨到 4、8 时的显存增幅。
  • 输入长度变长时 KV Cache 对显存和延迟的影响。

1B 模型在 FP16 下显存占用一般不高,实际数字受max_lengthbatch_sizedo_sample影响。给不了统一标准值,以实测为准。

7.3 CPU 推理与 GPU 推理差异

没有 GPU 时,纯 CPU 推理也能跑 1B 模型。速度会明显慢,但可以验证功能。

from transformers import AutoModelForCausalLM, AutoTokenizer model = AutoModelForCausalLM.from_pretrained("./models/aq-1b", torch_dtype=torch.float32)

CPU 推理建议加上 gen_kwargs 里的use_cache=True,否则会重复计算 KV,慢上加慢。

7.4 如何降低显存占用

  • 使用 8-bit 或 4-bit 量化:bitsandbytes加载时直接配置。
  • 开启low_cpu_mem_usage=True
  • 限制max_new_tokens,避免生成长文本时 KV Cache 膨胀。
  • 减少batch_size
  • 推理时不需要梯度,用torch.inference_mode()包裹。
model = AutoModelForCausalLM.from_pretrained( model_path, load_in_4bit=True, torch_dtype=torch.float16, device_map="auto", )

量化后的 1B 模型体积会更小,适合纯 CPU 或低显存设备。

7.5 进程残留和端口冲突

本地测试经常遇到服务停了但 GPU 显存没释放、端口还被占用的情况。

# 查看占用端口的进程 lsof -i :8000 # 清理残留 Python 进程 pkill -f api_server.py

不建议直接强杀所有 python 进程,先确认进程 PID 再停止。

8. 常见问题与排查方法

问题现象可能原因排查方式解决方案
模型加载报错找不到 config.json权重目录结构不对或下载不完整检查目录结构和文件大小重新下载完整权重
CUDA out of memory显存不足或 batch size 过大nvidia-smi查看显存降低 batch size、开量化、限制 max_new_tokens
生成的文本全是重复语句采样参数不合适或小模型退化观察输出规律调 temperature、加 repetition_penalty
中文输出质量差模型训练语料以英文为主检查数据和 tokenizer 词表换中文模型或做中文 SFT
API 请求超时生成 token 数过多或模型推理慢查看服务日志和耗时调低 max_new_tokens、加超时重试
端口被占用前一个服务未退出lsof -i :端口换端口或 kill 进程
CPU 推理速度很慢无 GPU 且模型未量化观察 CPU 占用用 4-bit 量化或换 GPU 环境
训练时 loss 不下降学习率过高或数据格式错误看 loss 曲线和日志调低学习率、检查数据预处理
微调后模型严重损坏只微调了 embedding 而没微调 lm_head检查模型结构保持输入输出层同步微调或冻结
从零训练显存不足batch size 或 sequence length 过大看训练日志中的 OOM 信息开梯度检查点、减小 batch size、用 DeepSpeed

9. 最佳实践与使用建议

9.1 先把复现成本降到最低

第一次跑这个项目,不要直接上全量训练。先把环境搭好、把 tokenizer 跑通、把数据管线跑通,再启动一个小规模的训练实验,例如 1000 条数据、训练 100 步,确认整个链路没有坑,再考虑扩大规模。

9.2 维护一套最小可运行配置

把能稳定运行的配置保存下来,包括依赖版本、模型路径、数据格式、推理参数。换环境时能快速恢复。

# 导出当前环境依赖 pip freeze > requirements_lock.txt

9.3 文件和日志分目录管理

推荐按这个结构组织任务目录:

experiments/ ├── 001-baseline/ │ ├── config/ │ ├── data/ │ ├── logs/ │ └── checkpoints/

训练日志、评估结果、推理输出分开存,方便复盘。

9.4 批量任务和接口服务注意点

批量推理任务一定要加日志、超时、失败重试。API 服务不要直接暴露公网,加一个简单的 Token 校验,或者用反向代理做访问控制,防止被当成免费算力滥用。

9.5 合规与授权边界

这个项目涉及从零训练、数据清洗、模型权重分发、内容生成等多个环节,每个环节都要注意:

  • 训练数据是否有版权、许可和隐私风险,涉及个人信息要脱敏或获得授权。
  • 模型生成内容要人工复核,不要未经测试直接对外商用。
  • 学术型模型在敏感领域的信息准确性有限,不能作为事实依据。
  • 涉及声音、人脸、私人数据等场景,严格遵循合法授权原则。

10. 总结与下一步

AQ 这个项目最值得关注的不是“1B 模型跑分有多高”,而是“两个人也能从零训出一个小 LLM”这件事本身。它把 LLM 的门槛重新拉回了训练技术本身,而不是拼算力堆参数量。

如果你对 LLM 训练感兴趣,第一步应该做的是:把项目仓库完整看一遍,确认数据来源、训练脚本、模型结构和评测结果;然后按本文的环境准备流程把推理环境搭好,下载权重,跑 5 组不同领域的提示词,验证模型输出是否符合预期;再跑一遍批量测试,确认稳定性。

最容易踩的坑有三个:一是权重下载不完整导致加载失败,二是显存估算错误导致 OOM,三是 1B 模型输出重复但不检查采样参数就直接判定模型不行。先把这三件事解决掉,再考虑复现训练或做微调。

后续可以扩展的方向:在这类 1B 从零训练模型的基础上做领域 SFT,例如学术摘要、代码生成、教学问答;也可以把它作为 Agent 编排里的轻量子模块;更深入一点,可以对比 AQ 和同等规模开源模型在相同评测集上的差异,分析训练数据配比和模型结构的实际影响。

这个项目适合收藏备用,尤其是想做 LLM 训练实验、又没有超大规模算力的读者。按项目 README 和本文的流程走一遍,你对从零训练 1B 模型会有更具体的体感。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询