Skip to content

Latest commit

 

History

205 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CUDAlab

CUDAlab 是一个用于学习和实验的大模型推理框架。项目用 C++17 和 CUDA 实现了模型加载、Tokenizer、Tensor、基础算子、KV Cache、Paged Attention、连续批处理调度等模块,当前主要支持 Llama/Llama3、Qwen2.5 和 Qwen3 系列模型的本地推理。

这个仓库适合用来理解一个轻量 LLM inference runtime 从模型权重到 token 输出的完整链路,而不是直接替代生产级推理服务。

功能特性

  • C++17/CUDA 推理核心
  • CPU 和 CUDA 双后端算子
  • Llama/Llama3、Qwen2.5、Qwen3 模型结构支持
  • SentencePiece、BPE/TikToken 风格 tokenizer 支持
  • FP32/FP16 权重导出入口
  • 普通自回归推理 demo
  • Paged KV Cache 和 Paged Attention
  • 简单 continuous batching 调度器
  • Paged Attention、KV Cache、Scheduler 等单元测试
  • Paged Attention 和 batch inference benchmark demo

目录结构

.
├── cmake/                    # CMake/CPM/CUDA 配置
├── demo/                     # 推理、批处理和 benchmark 示例
├── hf_infer/                 # HuggingFace 对照推理脚本
├── kuiper/
│   ├── include/              # 公开头文件
│   └── source/               # Runtime、模型、算子、调度器实现
├── models/                   # 本地模型文件目录,可自行放置 bin/tokenizer
├── test/                     # GTest 单元测试
├── tools/                    # HuggingFace/Meta 权重导出脚本
└── readme.md

核心模块:

  • kuiper/source/model: Llama、Qwen 模型前向流程
  • kuiper/source/op: embedding、matmul、rmsnorm、rope、mha、swiglu 等算子封装
  • kuiper/source/op/kernels: CPU/CUDA kernel 实现和后端分发
  • kuiper/source/paged_attention: Paged Attention 入口
  • kuiper/source/kv_cache: 分页 KV Cache 的 block table 和 block manager
  • kuiper/source/scheduler: 简单请求调度器
  • demo/batch_infer.cpp: 基于 scheduler 和 paged KV cache 的批量推理示例

依赖环境

基础依赖:

  • CMake 3.16+
  • C++17 编译器
  • CUDA Toolkit
  • glog
  • GTest
  • sentencepiece
  • Armadillo

启用 Llama3/Qwen2/Qwen3 时还需要:

  • abseil-cpp
  • re2
  • nlohmann_json

Python 导出脚本通常还需要:

  • Python 3
  • torch
  • transformers
  • numpy
  • sentencepiece
  • huggingface_hub 或 huggingface-cli

编译

默认编译基础库、测试和 demo:

mkdir -p build
cd build
cmake ..
make -j16

如果希望用 CPM 自动拉取部分 C++ 依赖:

mkdir -p build
cd build
cmake -DUSE_CPM=ON ..
make -j16

启用特定模型族支持:

# Llama3 / Llama3.2
cmake -DUSE_CPM=ON -DLLAMA3_SUPPORT=ON ..

# Qwen2.5
cmake -DUSE_CPM=ON -DQWEN2_SUPPORT=ON ..

# Qwen3
cmake -DUSE_CPM=ON -DQWEN3_SUPPORT=ON ..

构建产物一般位于:

build/demo/llama_infer
build/demo/batch_infer
build/demo/bench_paged_attention
build/test/test_llm
lib/libllama.so

如果你使用仓库里已有的 build-mini-vllm 目录,命令路径相应替换为 build-mini-vllm/demo/... 即可。

模型导出

项目推理程序读取自定义 .bin 权重格式。可以使用 tools/ 下脚本从 HuggingFace 或 Meta 权重导出。

Llama / Llama2

python3 tools/export_llama.py models/llama.bin --hf=/path/to/hf-llama --dtype=fp32

也可以使用 Meta 原始权重目录:

python3 tools/export_llama.py models/llama.bin --meta-llama=/path/to/meta/llama

Llama3 / Llama3.2

python3 tools/export_llama3.py models/llama3.bin --hf=/path/to/Llama-3.x --dtype=fp32

示例下载:

export HF_ENDPOINT=https://hf-mirror.com
huggingface-cli download --resume-download meta-llama/Llama-3.2-1B \
  --local-dir models/Llama-3.2-1B \
  --local-dir-use-symlinks False

python3 tools/export_llama3.py models/llama3_1b.bin --hf=models/Llama-3.2-1B

Qwen2.5

huggingface-cli download --resume-download Qwen/Qwen2.5-0.5B \
  --local-dir models/Qwen2.5-0.5B \
  --local-dir-use-symlinks False

python3 tools/export_qwen2.py models/qwen2_0.5b.bin --hf=models/Qwen2.5-0.5B

Qwen3

Qwen3 目前走两步导出:

python3 tools/export_qwen3/load.py \
  --model_name /path/to/Qwen3 \
  --output_file models/qwen3_weights.pth

python3 tools/export_qwen3/write_bin.py \
  --checkpoint models/qwen3_weights.pth \
  --model_name /path/to/Qwen3 \
  --device cpu

write_bin.py 默认输出 qwen0.6.bin。如果需要自定义输出文件名,可以在脚本中修改 file_path

单请求推理

Llama / Llama3

编译时启用对应选项后运行:

./build/demo/llama_infer models/llama3_1b.bin models/Llama-3.2-1B/tokenizer.json

如果是 SentencePiece tokenizer:

./build/demo/llama_infer models/llama.bin models/tokenizer.model

Qwen2.5

./build/demo/qwen_infer models/qwen2_0.5b.bin models/Qwen2.5-0.5B/tokenizer.json

Qwen3

./build/demo/qwen3_infer models/qwen0.6.bin /path/to/Qwen3/tokenizer.json

批量推理

demo/batch_infer.cpp 展示了一个简单的 continuous batching 流程:

./build/demo/batch_infer models/llama3_1b.bin models/Llama-3.2-1B/tokenizer.json \
  --request_num=8 \
  --max_batch_size=4 \
  --max_new_tokens=64 \
  --block_size=16 \
  --prompt=hello \
  --print=0

参数说明:

  • request_num: 总请求数
  • max_batch_size: 每轮最多处理的请求数
  • max_new_tokens: 每个请求最多生成 token 数
  • block_size: Paged KV Cache 每个 block 容纳的 token 数
  • prompt: 所有请求共用的输入 prompt
  • print: 是否打印每个请求的输出,1 打印,0 不打印

输出为 CSV 风格指标,包括生成 token 数、总耗时、吞吐、请求吞吐、平均延迟和 p95 延迟。

Benchmark

Paged Attention 和 Scheduler benchmark:

./build/demo/bench_paged_attention \
  --seq_len=512 \
  --head_num=8 \
  --head_size=64 \
  --kv_mul=1 \
  --block_size=16 \
  --repeat=100 \
  --request_num=64 \
  --max_batch_size=8 \
  --prompt_len=32 \
  --max_new_tokens=64

该程序会对比:

  • CPU contiguous MHA
  • CPU paged MHA
  • CUDA contiguous MHA
  • CUDA paged MHA
  • sequential scheduler
  • continuous scheduler

测试

编译后运行:

./build/test/test_llm

测试覆盖包括:

  • Tensor 和 Buffer
  • CUDA 基础算子
  • 模型加载和部分模型推理流程
  • Scheduler
  • KV Cache BlockManager
  • Paged Attention CPU/CUDA 对照

Paged Attention 调用链

paged_attention::forward 是 Paged Attention 的统一入口:

kuiper/source/model/llama3.cpp
  -> paged_attention::forward
     -> kernel::get_paged_mha_kernel(device_type)
        -> CPU:  kuiper/source/op/kernels/cpu/mha_kernel.cpp::paged_mha_kernel
        -> CUDA: kuiper/source/op/kernels/cuda/mha_kernel.cu::paged_mha_kernel_cu

相关文件:

  • kuiper/include/paged_attention/paged_attention.h
  • kuiper/source/paged_attention/paged_attention.cpp
  • kuiper/source/op/kernels/kernels_interfaces.cpp
  • kuiper/source/op/kernels/cpu/mha_kernel.cpp
  • kuiper/source/op/kernels/cuda/mha_kernel.cu

常见问题

找不到 nvcc

CMakeLists.txt 中默认写了:

set(CMAKE_CUDA_COMPILER "/usr/local/cuda/bin/nvcc")

如果 CUDA 安装在其他路径,需要修改这里或通过 CMake 参数指定 CUDA 编译器。

找不到 absl/re2/nlohmann_json

这些依赖只在启用 LLAMA3_SUPPORTQWEN2_SUPPORTQWEN3_SUPPORT 时需要。可以用:

cmake -DUSE_CPM=ON -DLLAMA3_SUPPORT=ON ..

让 CPM 尝试自动下载依赖;如果网络不可用,需要提前在系统环境中安装对应库。

tokenizer 路径怎么选

  • Llama/Llama2 通常使用 tokenizer.model
  • Llama3、Qwen2.5、Qwen3 通常使用 HuggingFace 模型目录下的 tokenizer.json

具体取决于 demo 中创建模型时选择的 TokenizerType

运行时找不到 libllama.so

可以在项目根目录运行可执行文件,或手动设置:

export LD_LIBRARY_PATH=$PWD/lib:$LD_LIBRARY_PATH

参考

本项目来自 KuiperInfer/KuiperLLama 系列学习项目,目标是用尽量清晰的代码展示大模型推理框架的关键组成部分:模型权重读取、Tokenizer、算子、CUDA 后端、KV Cache、Paged Attention 和批处理调度。

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages