- 下载模型权重
从 Hugging Face 下载 Llama 3.2 1B Instruct 的 model.safetensors 和 tokenizer.json、tokenizer_config.json,放置于项目指定的目录
(例如 ../../mode/LLM-Research/Llama-3.2-1B-Instruct/)。
- 修改CMakeLists.txt
在 CMakeLists.txt 调整自己的显卡架构以及文件位置:
set(CMAKE_CUDA_ARCHITECTURES 89)- 修改路径配置
在 main.cpp 中调整:
#define MODEL_ADDRESS "../../mode/LLM-Research/Llama-3.2-1B-Instruct/model.safetensors"
#define TOKENIZER_ADDRESS "../../mode/LLM-Research/Llama-3.2-1B-Instruct/"- 创建build文件夹 运行
make -j && ./ullm程序会提示输入问题(prompt),并逐步输出生成的 tokens(流式打印)。输入 q 退出。
所有超参数在 config.hpp 中定义,支持按模型调整:
| 参数 | 值 | 说明 |
|---|---|---|
| N_LAYERS | 16 | Transformer 层数 |
| EMBEDDING_LENGTH | 2048 | 隐层维度 |
| KV_DIM | 512 | K/V 总维度(8 头 × 64) |
| HEAD_DIM | 64 | 每个注意力头的维度 |
| NUM_Q_HEADS | 32 | Query 头数 |
| NUM_K_HEADS / NUM_V_HEADS | 8 | Key/Value 头数(GQA 比例 4:1) |
| MAX_SEQ_LEN | 2048 | 上下文窗口 |
| BLOCK_SIZE | 16 | PagedAttention 块大小(token 数) |
| KV_CACHE_SIZE_BYTES | 1 GB | KV Cache 总容量(可调) |
💡 切换模型时需同步调整以上参数。
main.cpp
├─ 加载 tokenizer & 权重
├─ 初始化 KVCacheManager(PagedAttention 块表)
├─ 循环处理用户输入
│ ├─ Prefill(首次处理提示词)
│ │ ├─ embeddingGather → RMSNorm → Q/K/V 投影 → RoPE
│ │ ├─ 写入 KV Cache(分块)
│ │ ├─ 计算注意力分数(GQA)→ Causal Mask → Softmax
│ │ ├─ 注意力输出 → O 投影 → 残差连接
│ │ ├─ MLP (SwigLU) → 残差连接 → 最终 RMSNorm → Logits
│ │ └─ 采样第一个 token(贪心)
│ ├─ Decode(自回归生成)
│ │ ├─ embeddingGatherDecode(仅当前 token)
│ │ ├─ Q 投影(单 token)→ RoPE(位置编码)
│ │ ├─ K/V 投影并写入 KV Cache(追加新 token)
│ │ ├─ PagedAttention(利用块表读取整个序列的 K/V)
│ │ ├─ 后续层计算(同 Prefill,但仅针对单 token)
│ │ └─ 采样下一 token → 重复直到结束
│ └─ 释放已完成序列的 KV 块
└─ 资源释放
.
├── kernels.cu # CUDA kernel 实现(RMSNorm、RoPE、Softmax、PagedAttention 等)
├── kernels.cuh # Kernel 函数声明
├── main.cpp # 主循环、交互逻辑
├── transformer.cpp # Prefill & Decode 流程(调用 cuBLAS 和 kernels)
├── transformer.hpp # 推理相关结构声明
├── safetensor.cpp # Safetensors 权重加载
├── safetensor.hpp
├── sampler.cpp # 采样器(当前仅贪心,可扩展温度采样)
├── sampler.hpp
├── tokenizer.cpp # 基于 tokenizer.cpp 库的分词封装(源码已整合)
├── tokenizer.hpp
├── tensor.hpp # Tensor 类(管理 GPU/CPU 内存)
├── config.hpp # 所有超参数、Weights 结构体
├── json.hpp # nlohmann/json 单头文件
└── README.md
模型权重来自 Llama 3.2(Meta)。
分词器组件基于 tokenizer.cpp 实现,其源码已直接整合至本项目。
参考了 FlashAttention 和 vLLM 的设计思想。
- 支持批量推理(Batch > 1)
- 实现温度采样和 Top-K/Top-P
- 支持动态序列长度(当前 MAX_SEQ_LEN 固定)
- 优化 RoPE 计算(减少重复计算)
- 集成更多模型架构(如 Mistral、Qwen)
- 添加性能基准测试(吞吐量、延迟)