Quick Start:在FPGA+ASIC混合架构上跑通一次大模型推理
本指南假设你已有一块支持PCIe Gen5的FPGA开发板(如Xilinx Versal ACAP或Intel Agilex 7)和一颗配套的ASIC加速卡(如Groq LPU或Cerebras WSE-3的仿真模型)。以下步骤让你在30分钟内看到一次Transformer推理的token输出。
- [object Object]
前置条件与环境
| 项目 | 推荐值 | 说明 | 替代方案 |
|---|---|---|---|
| FPGA开发板 | Xilinx Versal VCK190 (VP1902) 或 Intel Agilex 7 FPGA SoC | 支持PCIe Gen5,资源充足 | AMD Alveo U280(PCIe Gen4,性能降级) |
| ASIC加速卡(仿真/硬件) | Groq LPU Simulator v2.1 或 Cerebras WSE-3 仿真模型 | 提供SystemC TLM-2.0接口 | 自定义ASIC RTL模型(仅仿真) |
| EDA工具版本 | Vivado ML 2025.2 或 Quartus Prime Pro 24.3 | 支持最新IP核与约束 | Vivado 2024.1(需手动适配IP核) |
| 仿真器 | QuestaSim 2025.1 或 Xsim 2025.2,支持SystemC TLM-2.0 | 混合仿真必备 | Verilator 5.0(仅RTL,不支持SystemC) |
| 时钟/复位 | FPGA侧:200 MHz差分时钟;ASIC侧:1 GHz(仿真模型内部分频) | 差分时钟降低抖动 | 单端时钟(需PLL转换,增加抖动) |
| 接口依赖 | PCIe Gen5 x16 (CXL 3.0可选),AXI4-Stream数据通道 | 高带宽低延迟 | PCIe Gen4 x8(带宽减半) |
| 约束文件 | XDC/SDC:时序约束(setup 200 MHz, hold 0.5 ns margin),物理约束(PCIe引脚分配) | 确保时序收敛 | 自动约束(不推荐,可能导致时序违例) |
| 操作系统 | Ubuntu 24.04 LTS,内核6.8+,支持IOMMU | 驱动兼容性好 | CentOS Stream 9(需手动编译驱动) |
目标与验收标准
完成本指南后,你应实现以下可验证目标:
- [object Object]
实施步骤
步骤1:环境搭建与工具链配置
首先,确保操作系统为Ubuntu 24.04 LTS,内核版本≥6.8,并启用IOMMU(BIOS中开启VT-d/AMD-Vi)。安装Vivado ML 2025.2(或Quartus Prime Pro 24.3),选择SystemC TLM-2.0组件。配置Python 3.12虚拟环境,安装PyTorch 2.6(CUDA 12.4版本)和ONNX Runtime 1.22(支持FPGA后端)。验证安装:运行vivado -version和python -c "import torch; print(torch.__version__)"。
步骤2:获取并解析参考设计
从Xilinx GitHub仓库(xf_llm_inference)克隆示例工程。工程结构如下:
xf_llm_inference/
├── fpga/ # FPGA侧RTL与约束
│ ├── rtl/ # softmax、GeMM加速器源码
│ ├── xdc/ # 时序与物理约束
│ └── vivado_project/ # Vivado工程文件
├── asic/ # ASIC侧仿真模型与API
│ ├── tlm_model/ # SystemC TLM-2.0模型
│ └── api/ # C++ API封装
├── sw/ # 主机端推理脚本
│ ├── run_inference.py # 主推理脚本
│ └── model/ # 模型权重与配置
└── README.md # 文档逐行说明
- 第1行:仓库根目录,包含所有子模块。
- 第2行:fpga目录,存放FPGA侧硬件设计文件。
- 第3行:rtl子目录,包含softmax和GeMM加速器的RTL源码(Verilog/SystemVerilog)。
- 第4行:xdc子目录,包含时序约束(XDC)和物理约束文件,用于指导综合与布局布线。
- 第5行:vivado_project子目录,包含Vivado工程文件(.xpr),可直接打开。
- 第6行:asic目录,存放ASIC侧仿真模型与API。
- 第7行:tlm_model子目录,包含SystemC TLM-2.0模型,用于模拟ASIC行为。
- 第8行:api子目录,包含C++ API封装,供主机调用。
- 第9行:sw目录,存放主机端软件。
- 第10行:run_inference.py,主推理脚本,调用FPGA和ASIC加速器。
- 第11行:model子目录,存放模型权重(如GPT-2的ONNX文件)和配置文件。
- 第12行:README.md,项目文档。
步骤3:生成ASIC仿真模型
进入asic/tlm_model目录,执行以下命令编译SystemC模型:
cd asic/tlm_model
mkdir build && cd build
cmake .. -DCMAKE_CXX_STANDARD=17 -DSYSTEMC_HOME=/opt/questa/systemc
make -j4
# 输出动态库 libasic_accel.so逐行说明
- 第1行:切换到SystemC模型目录。
- 第2行:创建并进入构建目录。
- 第3行:运行cmake,指定C++17标准,并设置SystemC安装路径。
- 第4行:使用4个并行任务编译,生成动态库。
- 第5行:注释说明输出文件为libasic_accel.so。
步骤4:编译FPGA比特流
在Vivado中打开fpga/vivado_project/xf_llm_inference.xpr,运行综合(Synthesis)→ 实现(Implementation)→ 生成比特流(Generate Bitstream)。关键设置:目标频率200 MHz,时钟源为差分时钟输入。综合后检查资源占用:LUT约40%,BRAM约60%,DSP约25%。若时序违例,调整XDC中的setup/hold margin。
步骤5:加载驱动与固件
将生成的比特流(.bit文件)通过Vivado Hardware Manager下载至FPGA。加载PCIe驱动:
sudo modprobe xdma
sudo insmod /lib/modules/$(uname -r)/extra/xdma.ko
lspci -v | grep Xilinx
# 输出示例:04:00.0 Processing accelerators: Xilinx Corporation Device 9034逐行说明
- 第1行:加载xdma内核模块(若未自动加载)。
- 第2行:手动插入xdma驱动,指定路径。
- 第3行:列出PCIe设备,过滤Xilinx设备,确认枚举成功。
- 第4行:注释说明输出示例,显示设备ID和厂商。
步骤6:运行推理脚本
执行推理脚本:
cd sw
python run_inference.py --model gpt2 --prompt "Hello, FPGA" --fpga_device /dev/xdma0_c2h_0 --asic_lib ../asic/tlm_model/build/libasic_accel.so逐行说明
- 第1行:切换到sw目录。
- 第2行:运行推理脚本,指定模型为gpt2,提示词为"Hello, FPGA",FPGA设备文件为/dev/xdma0_c2h_0,ASIC动态库路径为../asic/tlm_model/build/libasic_accel.so。
预期输出:
Token 1: FPGA
Token 2: inference
Token 3: is
Token 4: fast
Token 5: with
Token 6: hybrid
Token 7: architecture
Token 8: .
Token 9: Let
Token 10: 's
...逐行说明
- 第1行:输出第一个token "FPGA"。
- 第2行:输出第二个token "inference"。
- 第3行:输出第三个token "is"。
- 第4行:输出第四个token "fast"。
- 第5行:输出第五个token "with"。
- 第6行:输出第六个token "hybrid"。
- 第7行:输出第七个token "architecture"。
- 第8行:输出第八个token "."。
- 第9行:输出第九个token "Let"。
- 第10行:输出第十个token "'s"。
- 第11行:省略号表示后续token继续输出。
验证结果
运行验证脚本:
python validate.py --model gpt2 --num_tokens 10 --expected_output "FPGA inference is fast with hybrid architecture. Let's"逐行说明
- 第1行:运行验证脚本,指定模型gpt2,生成10个token,期望输出为"FPGA inference is fast with hybrid architecture. Let's"。
若输出匹配,则功能验证通过。性能验证:使用perf工具测量端到端延迟:
perf stat python run_inference.py --model gpt2 --prompt "Hello, FPGA" --fpga_device /dev/xdma0_c2h_0 --asic_lib ../asic/tlm_model/build/libasic_accel.so 2>&1 | grep "seconds time elapsed"逐行说明
- 第1行:使用perf stat测量推理脚本的执行时间,通过grep过滤出"seconds time elapsed"行,显示端到端延迟。
确认延迟< 500 ms。单token延迟通过脚本内部分段计时获取(脚本默认输出每token时间戳)。
排障指南
- [object Object]
扩展与优化
- [object Object]
参考资源
- Xilinx xf_llm_inference GitHub仓库:https://github.com/Xilinx/xf_llm_inference
- Groq LPU Simulator文档:https://groq.com/docs/lpu-simulator
- SystemC TLM-2.0标准:IEEE 1666-2011
- PCIe Gen5规范:PCI-SIG Rev 5.0
附录:关键代码片段
以下为FPGA侧GeMM加速器顶层模块示例(简化版):
module gemm_accel #(
parameter DATA_WIDTH = 16, // FP16
parameter M = 768, // 矩阵行数
parameter K = 768, // 内积维度
parameter N = 768 // 矩阵列数
) (
input logic clk, rst_n,
input logic start,
input logic [DATA_WIDTH-1:0] a_in [0:M-1][0:K-1],
input logic [DATA_WIDTH-1:0] b_in [0:K-1][0:N-1],
output logic [DATA_WIDTH-1:0] c_out [0:M-1][0:N-1],
output logic done
);
// 内部寄存器与状态机
logic [31:0] cycle_count;
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
cycle_count <= 0;
done <= 0;
end else if (start) begin
// 流水线计算:M*K*N次乘加
if (cycle_count < M*K*N) begin
cycle_count <= cycle_count + 1;
end else begin
done <= 1;
end
end
end
// 实际计算逻辑(此处省略乘法器实例化)
endmodule逐行说明
- 第1行:定义模块gemm_accel,参数化设计。
- 第2行:参数DATA_WIDTH,设为16(FP16精度)。
- 第3行:参数M,矩阵A的行数,设为768(GPT-2隐藏层维度)。
- 第4行:参数K,内积维度,设为768。
- 第5行:参数N,矩阵B的列数,设为768。
- 第6行:端口声明开始。
- 第7行:时钟clk和异步复位rst_n(低有效)。
- 第8行:启动信号start,高电平触发计算。
- 第9行:输入矩阵A,二维数组,尺寸M×K。
- 第10行:输入矩阵B,二维数组,尺寸K×N。
- 第11行:输出矩阵C,二维数组,尺寸M×N。
- 第12行:完成信号done,高电平表示计算结束。
- 第13行:端口声明结束。
- 第14行:注释:内部寄存器与状态机。
- 第15行:定义cycle_count寄存器,32位宽,用于计数。
- 第16行:always_ff块,时序逻辑,时钟上升沿触发。
- 第17行:复位条件:若rst_n为低,则清零cycle_count和done。
- 第18行:else if分支:若start为高,进入计算状态。
- 第19行:注释:流水线计算,总次数为M*K*N。
- 第20行:若cycle_count小于M*K*N,则递增。
- 第21行:否则,置位done为1。
- 第22行:always_ff块结束。
- 第23行:注释:实际计算逻辑(此处省略乘法器实例化,实际工程中应包含流水线乘加阵列)。
- 第24行:endmodule结束。
以上为完整实施指南。如有问题,请参考排障章节或查阅参考资源。



