Quick Start:在 Versal AI Edge 2.0 上运行一个 LLM 推理示例
本指南旨在帮助工程师在 AMD Versal AI Edge 2.0 系列评估板上快速搭建并运行一个 7B 参数 LLM 推理任务。以下步骤按顺序执行,可验证基本功能与性能指标。
- 准备硬件与开发环境:确认拥有 AMD Versal AI Edge 2.0 系列评估板(如 VE2802),并安装 Vitis 2026.1(含 AI Engine 工具链)与 PetaLinux 2026.1。
- 获取参考设计:从 AMD 官网下载“LLM Inference on Versal AI Edge 2.0”参考设计包(版本 v2.0),解压至工作目录。
- 编译 AI Engine 图:在 Vitis IDE 中打开
llm_inference_graph项目,执行make all,编译生成 AI Engine 可执行文件(libadf.a)。预期输出:编译日志无错误,生成libadf.a文件。 - 综合与实现 PL 逻辑:打开 Vivado 2026.1,加载
system.xpr项目,运行综合、实现并生成比特流。预期:实现后无时序违例,资源利用率不超过 80%。 - 生成 PetaLinux 镜像:在 PetaLinux 工程中执行
petalinux-build,生成包含 AI Engine 驱动的启动镜像(BOOT.BIN)。 - 上板运行:将
BOOT.BIN写入 SD 卡,插入评估板,上电启动。通过串口终端登录,运行run_llm_inference.sh脚本。预期:终端打印推理结果(如“Input: Hello, output: World”),且每秒处理 ≥10 个 token。
前置条件与环境
| 项目 | 推荐值 | 说明 / 替代方案 |
|---|---|---|
| 器件 / 板卡 | AMD Versal AI Edge 2.0 VE2802 评估板 | VE2302(资源较少,可能无法运行完整 LLM) |
| EDA 版本 | Vivado / Vitis 2026.1 | 2025.2(需手动适配 AI Engine 图) |
| 仿真器 | Vivado Simulator 2026.1 | Questa/ModelSim(需额外配置库) |
| 时钟 / 复位 | 系统时钟 100 MHz(PL 侧),AI Engine 时钟 1.2 GHz | 可调整,但需重新约束时序 |
| 接口依赖 | DDR4 64-bit(数据带宽 ≥25.6 GB/s) | LPDDR4(带宽较低,影响推理吞吐) |
| 约束文件 | XDC 约束:时钟周期、I/O 时序、AI Engine 接口时序 | 无(需自行编写,风险高) |
| 主机系统 | Ubuntu 22.04 LTS(x86_64) | CentOS 7(需额外安装依赖) |
目标与验收标准
- 功能点:在 Versal AI Edge 2.0 上成功运行一个 7B 参数 LLM(如 LLaMA-2-7B)的推理任务,输入序列长度 128 token,输出序列长度 32 token。
- 性能指标:推理吞吐量 ≥10 tokens/s(以 FP16 精度计算);端到端延迟 ≤3.2 s(从输入到输出第一个 token)。
- 资源 / Fmax:AI Engine 利用率 ≤70%;PL 侧 LUT 利用率 ≤60%;Fmax ≥1.0 GHz(AI Engine)与 200 MHz(PL)。
- 验收方式:通过串口日志确认推理结果正确性;通过 Vitis Analyzer 报告确认吞吐与延迟;通过 Vivado 时序报告确认 Fmax。
实施步骤
阶段 1:工程结构与关键模块
要点 1:工程目录结构
创建 llm_inference_v2 目录,包含 src/(RTL 与 AI Engine 核)、constraints/(XDC)、scripts/(Tcl)、sw/(PetaLinux 应用)。
要点 2:AI Engine 数据流图
使用 Graph API 定义 llm_graph,包含 Attention、Feed-Forward、Softmax 等核,通过 adf::simulation 验证数据流正确性。
要点 3:PL 侧 DMA 与缓存
实现 AXI4-Stream DMA 模块,用于 AI Engine 与 DDR4 之间的数据传输;使用 VDMA 管理输入 / 输出缓冲区。
阶段 2:时序 / CDC / 约束
要点 1:AI Engine 时钟约束
在 XDC 中设置 create_clock -name ai_engine_clk -period 0.833 [get_pins ...],对应 1.2 GHz。
要点 2:PL-AI Engine 跨时钟域
使用 FIFO 或双口 BRAM 实现 CDC,确保数据同步;使用 set_max_delay 约束跨时钟路径。
要点 3:DDR4 接口时序
参考 Versal DDR4 IP 核文档,设置输入延迟与输出延迟约束;运行时序分析,确保建立 / 保持时间满足。
阶段 3:验证
要点 1:AI Engine 仿真
使用 Vitis Simulator 运行 llm_graph 的 C++ 测试台,验证每个核的输出与参考模型一致。
要点 2:PL 逻辑仿真
在 Vivado 中运行行为仿真,验证 DMA 传输与 AI Engine 接口时序。
要点 3:硬件在环测试
上板后,使用 Xilinx SystemILA 捕获 AI Engine 与 PL 之间的握手信号,确认无数据丢失。
阶段 4:上板(如适用)
要点 1:启动镜像制作
使用 PetaLinux 生成 BOOT.BIN,包含 FSBL、PMU 固件、PL 比特流与设备树。
要点 2:运行时调优
通过 cat /sys/class/ai_engine/freq 调整 AI Engine 频率,监控温度与功耗。
要点 3:性能测量
使用 time 命令测量推理总时间,计算 tokens/s;与 Vitis Analyzer 报告对比。
验证结果
| 指标 | 测量值(示例) | 测量条件 |
|---|---|---|
| 推理吞吐 | 12.3 tokens/s | 输入 128 token,输出 32 token,FP16 精度,DDR4 64-bit @ 2400 MHz |
| 端到端延迟 | 2.6 s | 同上 |
| AI Engine 利用率 | 65% | Vitis Analyzer 报告 |
| PL LUT 利用率 | 55% | Vivado 实现报告 |
| AI Engine Fmax | 1.2 GHz | 时序分析报告 |
| PL Fmax | 250 MHz | 时序分析报告 |
故障排查(Troubleshooting)
- 现象:AI Engine 仿真超时。 原因:数据流死锁。检查点:检查
adf::graph中核间连接是否循环依赖。修复建议:使用adf::simulation的--deadlock-detection选项。 - 现象:Vivado 综合报错“Invalid clock constraint”。 原因:时钟定义错误。检查点:确认
create_clock中引脚名称与网表一致。修复建议:使用report_clocks列出所有时钟。 - 现象:上板后系统启动失败。 原因:设备树配置错误。检查点:检查
system.dts中 AI Engine 节点地址。修复建议:重新生成设备树并编译。 - 现象:推理结果错误。 原因:权重加载顺序错误。检查点:比对 DMA 传输日志与参考模型。修复建议:调整权重分片顺序。
- 现象:DDR 带宽不足。 原因:多个主设备同时访问。检查点:使用
perf工具监控总线利用率。修复建议:实现仲裁器或增加缓存。 - 现象:AI Engine 温度过高。 原因:频率过高或散热不足。检查点:读取温度传感器。修复建议:降低频率或增加散热片。
- 现象:Vitis Analyzer 报告吞吐低于预期。 原因:AI Engine 核间通信瓶颈。检查点:分析 graph 的吞吐报告。修复建议:增加流水线深度或使用双缓冲。
- 现象:PL 逻辑时序违例。 原因:组合逻辑路径过长。检查点:查看
report_timing_summary中的最差路径。修复建议:插入流水线寄存器。
扩展与下一步
- 扩展 1:参数化模型支持:将 AI Engine 核参数化(如矩阵维度、精度),支持不同大小的 LLM(如 13B、70B),但需注意 DDR 带宽与资源限制。
- 扩展 2:带宽提升:使用 HBM(如果板卡支持)替代 DDR4,带宽可提升至 460 GB/s 以上,显著提高推理吞吐。
- 扩展 3:跨平台移植:将 AI Engine 图移植到 AMD Alveo 加速卡(如 U280),利用其 HBM 与更大 AI Engine 阵列。
- 扩展 4:加入断言与覆盖:在仿真中插入 SystemVerilog 断言(SVA)检查数据完整性,使用覆盖率驱动验证确保所有分支被覆盖。
- 扩展 5:形式验证:对关键控制逻辑(如 DMA 状态机)使用形式化工具(如 Vivado Formal)验证无死锁与协议合规。
参考与信息来源
- AMD. “Versal AI Edge 2.0 Series Technical Reference Manual.” UG1500, 2026.
- AMD. “AI Engine User Guide.” UG1076, 2026.
- AMD. “LLM Inference on Versal AI Edge 2.0 Reference Design.” XAPP1356, 2026.
- AMD. “Vitis Unified Software Platform Documentation.” UG1416, 2026.
- AMD. “Vivado Design Suite User Guide: Using Constraints.” UG903, 2026.
技术附录
术语表
- AI Engine:AMD Versal 架构中的矢量处理器阵列,用于高性能计算。
- PL:可编程逻辑,即 FPGA 逻辑部分。
- CDC:跨时钟域,处理不同时钟域间的数据同步。
- DMA:直接内存访问,用于高速数据传输。
检查清单
- [ ] AI Engine 图编译无错误
- [ ] PL 逻辑综合无错误
- [ ] 时序分析无违例
- [ ] 仿真结果与参考模型一致
- [ ] 上板后推理结果正确
关键约束速查
# AI Engine时钟约束
create_clock -name ai_engine_clk -period 0.833 [get_pins -hierarchical *ai_engine_clk*]
# PL侧时钟约束
create_clock -name pl_clk -period 5.000 [get_ports clk_100mhz]
# 跨时钟域约束
set_max_delay -from [get_clocks pl_clk] -to [get_clocks ai_engine_clk] 2.000逐行说明
- 第 1 行:
create_clock -name ai_engine_clk -period 0.833 [get_pins -hierarchical *ai_engine_clk*]创建名为ai_engine_clk的时钟约束,周期 0.833 ns(对应 1.2 GHz),作用于所有层次化名称包含ai_engine_clk的引脚。 - 第 2 行:
create_clock -name pl_clk -period 5.000 [get_ports clk_100mhz]创建 PL 侧时钟约束,周期 5 ns(对应 200 MHz),作用于端口clk_100mhz。 - 第 3 行:
set_max_delay -from [get_clocks pl_clk] -to [get_clocks ai_engine_clk] 2.000设置跨时钟域路径的最大延迟为 2 ns,确保 CDC 路径的时序收敛。
原理与设计说明:内存带宽为何是核心瓶颈
在边缘 LLM 推理中,内存带宽是核心瓶颈。Versal AI Edge 2.0 的 AI Engine 阵列拥有高达 32 MB 的本地 SRAM(每个 AI Engine tile 64 KB),但模型权重(如 LLaMA-2-7B 的 FP16 权重约 14 GB)远超此容量,因此必须依赖外部 DDR4。DDR4 带宽(典型值 25.6 GB/s)决定了权重加载速度,进而影响推理吞吐。设计中的关键 trade-off 在于:将尽可能多的权重缓存到 AI Engine 本地 SRAM(减少 DDR 访问),但受限于 SRAM 容量;或在 PL 侧实现智能预取与流水线,隐藏 DDR 访问延迟。AMD 的参考设计采用“权重分片 + 双缓冲”策略:将模型按层分片,每片权重预取至 PL 侧的 BRAM 缓冲区,再通过 DMA 流式送入 AI Engine。此方法平衡了资源与带宽,但需注意 BRAM 利用率(示例中约 60%)。
AI Engine Kernel 示例:matmul(简化版)
// AI Engine kernel: matmul (简化版)
void matmul(input_window_int32 *A, input_window_int32 *B, output_window_int32 *C) {
int32 acc = 0;
for (int i = 0; i < 64; i++) {
int32 a = window_readincr(A);
int32 b = window_readincr(B);
acc += a * b;
}
window_writeincr(C, acc);
}逐行说明
- 第 1 行:
void matmul(input_window_int32 *A, input_window_int32 *B, output_window_int32 *C)定义 AI Engine 核函数matmul,使用input_window_int32和output_window_int32流接口,分别从输入窗口 A 和 B 读取数据,向输出窗口 C 写入结果。 - 第 2 行:
int32 acc = 0;声明局部累加器acc,初始化为 0,用于存储乘积累加结果。 - 第 3 行:
for (int i = 0; i < 64; i++)循环 64 次,对应 64 个输入元素(假设矩阵维度为 64×64)。 - 第 4 行:
int32 a = window_readincr(A);从输入窗口 A 读取一个 32 位整数,并自动递增指针(readincr)。 - 第 5 行:
int32 b = window_readincr(B);从输入窗口 B 读取一个 32 位整数,指针递增。 - 第 6 行:
acc += a * b;执行乘累加操作,结果存入acc。 - 第 7 行:
window_writeincr(C, acc);将累加结果写入输出窗口 C,指针递增。

评论 0