记一次在Kria KV260上部署语言模型Llama.c全流程
零、说在前面1. 本文主要参考了日语blog言語モデルを高位合成でFPGAに実装してみた补充了其中细节并记录了本小白在复刻过程中遇到的坑。这篇blog在创作过程中也参考了几乎所有关于Kria KV260的教程不得不吐槽Xilinx虽然文档多但是管理真的乱很感谢前辈们能把经验分享出来。这里糅合了各位大佬的文章、视频、代码以及一些自己的理解被作者厚着脸皮贴了原创的标签。引用的文章链接会尽量在引用段落后标出。如果构成了抄袭请联系作者作者马上删掉。2. 由于本小白买不起一手的Kria KV260所以要自行查阅配置要求选购配件。以下是部署LLM的外设准备清单高速SD卡 必须12V 3A 5.5*2.5mm接口的直流供电 必须MicroUSB线必须无线USB网卡 或 网线非必须但强烈推荐一套键鼠非必须HDMI线外接显示屏非必须3. Kria KV260插入顺序不按照这个顺序貌似会导致读不出卡 / 串口先插SD卡然后是MicroUSB线最后接上12V电源4. 如果你已经非常熟悉KV260可以直奔第三部分。那么一起开始吧。一、配置Kria KV2601. 测试与烧录SD卡一定要选用正经厂商推荐闪迪与三星生产的高速SD卡这点有很多博主提到过SD卡的读写速度将影响你后续所有开发体验。本小白怒亏18.8元买来的杂牌SD卡读写只有惊人的2MB/s相比之下后来目前使用的EMTEC写入能达到30MB/s左右三星的EVO PLUS则更好。可以用Crystaldiskmark测试读写速度。顺带一提经过验证USB2.0读卡器也能勉强使用只是烧录比较慢需要10分钟左右。接下来就要往SD卡中烧录Xilinx自己的Ubuntu发行版这里一定要选择22.04可以从这个ubuntu的amd专属下载界面下载Install Ubuntu on AMD | Ubuntu需要你注册一个免费的AMD账号。原日文教程中使用的是20.04但是20.04不包含xmutil还要安装 / 配置很麻烦。不过注意多个博主提到如果你是新买的Kria KV260并想运行更新版本的ubuntu那需要先下载20.04更新完固件之后再刷高版本的。24.04 则基本上全是bug不要碰。绝大部分博主包括官方都推荐使用balena etcher往SD卡里烧录具体可以参考这个CSDN blog。如果这对你有用那皆大欢喜但是如果balena etcher提示烧录或验证失败先不要怀疑你的设备换成Rufus试试 - 这是一个更轻量化对Windows优化更好的烧录软件是一个只有2MB的.exe。需要注意的是下载下来的原始文件是img.xz。对于balena etcher不需要解压即可烧录。但是对于Rufus需要先手动解压成.img再喂给它。最后烧录到100%会跳个奇怪的提示除非明确报错我并没有遇到不管它并推出SD卡就行。现在可以把SD卡插入到KV260的卡槽中。2. 串口通信然后将KV260通过MicroUSB线缆连接到你的电脑。这里串口通信app有非常多的途径比如说teraterm或者另一个blog中提到的无线缆ssh连接mobaXterm。我使用的是PlatformIO vscode插件中推荐的telepot可以通过vscode - PlatformIO - Miscellaneous - Serial UDP Plotter获取。然后New Terminal输入pio device list会给你跳出来两个COM口假设你没有连接其他USB设备。我这里是COM9和COM10其中数字小的COM9对应着板子的串口控制器于是乎输入pio device monitor -p COM9 -b 115200以此监视串口。3. KV260启动现在万事俱备可以插上电源了。不出意外的话串口通讯会输出一长串自检信息并最终顺利地让你开始配置ubuntu的密码。默认账号密码为ubuntu/ubuntu。外接屏幕如果有的话也会显示熟悉的gnome登录界面。至此KV260就配置完成。二、运行官方例程在实际运行任何东西之前很有必要测试自己的环境配置是否正常。运行官方提供的教程就是一个很好的sanity checkCustom-Platform-Creation-Tutorial-on-MPSoChttps://docs.amd.com/r/en-US/Vitis-Tutorials-Vitis-Platform-Creation/Custom-Platform-Creation-Tutorial-on-MPSoC简单来说这个教程做了通过vivado创建硬件平台上的kv260_hardware_platform.xsa将此.xsa文件导入到vitis创建硬件平台和vadd例程把包含软硬件信息的组合包放到KV260上运行但是不得不再次吐槽AMD教程更新真的就只是把年份数字变一下我强烈怀疑是不是根本没跑过甚至没读过。版本根本不适配。1. 创建vivado hardware design和.xsa这里貌似没什么好说的跟着链接中的教程走就行了。其中vivado软件相对于教程有些更新比如说教程中的ps8_0_axi_periph实际上被更名为axi_smc。不影响。2. 创建vitis platform有几点官方教程中写的有点含糊特此记录Common image直接在这个Downloads页面找或者直接点这个链接ZYNQMP common image。注意这里我们下载的是2022.2版本的用于适配22.04版本的Ubuntu不然生成的文件版本太高之后上板会报错./vadd_host: /lib/aarch64-linux-gnu/libc.so.6: version GLIBC_2.38 not found (required by ./vadd_host) ./vadd_host: /lib/aarch64-linux-gnu/libstdc.so.6: version GLIBCXX_3.4.32 not found (required by ./vadd_host)下载到WorkSpace之后解压tar xvf xilinx-zynqmp-common-v2022.2_10141622.tar.gz -C .在WorkSpace/xilinx-zynqmp-common-v2022.1路径下执行./sdk.sh -d Install Target Dir时按照官方推荐的路径应该是./sdk.sh -d ~/Projects/KV260_Study/xilinx-zynqmp-common-v2022.2这样方便管理之后也可以动态切换image版本。官方在创建vitis platform component的时候很顺利但是我在OS and Processor那一步遇到了Error: Error in generating Processor List. 经过xsct检查我vivado那一步生成的xsa是正常的在别的设备上都能用就我的WSL Ubuntu22.04不行。一气之下卸载重装了整个WSL就好了。Vitis或者xsct有个很逆天的23年的bug还没修大概是是报xtclsh … rlwrap … Segmentation fault之类的。这不仅会在你尝试使用xsct时候报错还会在build binary container的时候报错。具体问题描述和修复方式来自于这个amd社区高赞答案链接sudo apt install rlwrap cd vitis installation path/bin/unwrapped/lnx64.o/ sudo mv rlwrap rlwrap.old sudo ln -s /usr/bin/rlwrap rlwrap如果你报错--platform: Permission Deinied之类的那也许是你在用2025.1版本的common image请你返回第一步重新下载或者手动link一下来生成xclbin文件v -l \ --platform /home/ruhai/Projects/KV260_Study/WorkSpace/kv260_custom/export/kv260_custom/kv260_custom.xpfm \ --target hw \ /home/ruhai/Projects/KV260_Study/WorkSpace/vadd_vadd/vadd/vadd.xo \ --config /home/ruhai/Projects/KV260_Study/WorkSpace/vadd/hw_link/vadd-link.cfg \ -o /home/ruhai/Projects/KV260_Study/WorkSpace/vadd/build/hw/hw_link/vadd.xclbin然后貌似要先在vitis中新建一个terminal运行unset LD_LIBRARY_PATH source ~Projects/KV260_Study/xilinx-zynqmp-common-v2022.2/environment-setup-cortexa72-cortexa53-xilinx-linux然后再build如果你遇到bits/cconfig.h: No such file or directory或者类似的基础toolchain方面的报错那就试试手动在vadd_host下的vitis-comp.json把Use Sysroot Toolchain勾选上然后路径选择/xilinx-zynqmp-common-v2024.2/sysroots/x86_64-petalinux-linux/usr/bin/aarch64-xilinx-linux2.1 一些供复制的常用命令由于我没钱买网卡但是手边有U盘于是所有硬件需要挂载的文件都是靠U盘传输的。用scp传输会方便很多。以下命令不包含创建shell.json。# 新建目标文件夹 mkdir -p /mnt/d/2022_vadd_bundle # 复制 pl.dtbo cp ~/Projects/KV260_Study/WorkSpace/bundle_for_board/pl.dtbo /mnt/d/2022_vadd_bundle/ # 复制并重命名 vadd.xclbin - binary_container_1.bin cp ~/Projects/KV260_Study/WorkSpace/vadd/build/hw/hw_link/vadd.xclbin /mnt/d/2022_vadd_bundle/binary_container_1.bin # 复制 vadd_host cp ~/Projects/KV260_Study/WorkSpace/vadd_host/build/hw/vadd_host /mnt/d/2022_vadd_bundle/ # 以下在kv260上运行 # 新建kv260上目标应用目录 sudo mkdir -p /lib/firmware/xilinx/vadd # 进入 U 盘目录 cd /media/ubuntu/0012-0CBA/2022_vadd_bundle # 把文件复制到系统目录 sudo cp pl.dtbo binary_container_1.bin shell.json /lib/firmware/xilinx/vadd3. 测试# 查看当前已注册的应用 sudo xmutil listapps # 卸载旧的应用如果有 sudo xmutil unloadapp # 加载新的 vadd 应用 sudo xmutil loadapp vadd # 加载安静的k26-starter-kits sudo xmutil loadapp k26-starter-kits # 确保 vadd_host 可执行 cp vadd_host /home/ubuntu chmod x ./vadd_host # 运行测试 ./vadd_host binary_container_1.bin# 测试结束删除目标目录 rm -rf /lib/firmware/xilinx/vadd三、部署Llama.c来到了关键。1. 准备先克隆swan下载TinyStories15M模型和tokenizergit clone gitgithub.com:turingmotors/swan.git cd swan # 下载模型和tokenizer mkdir model wget https://huggingface.co/karpathy/tinyllamas/resolve/main/stories15M.bin -O model/stories15M.bin wget https://raw.githubusercontent.com/leloykun/llama2.cpp/master/tokenizer.bin -O model/tokenizer.bin # 编译。这将会在你的PC上运行LLM模型作为测试 mkdir build cd build cmake .. make cd .. ./build/swan输出2. 构建mkdir kv260_swan cd kv260_swan vitis -w .然后跟着2.1创建一个一模一样的kv260 hardware platform和kv260_custom这里按照官方教程走就行不多赘述。2.1 新建Vitis System Project选择File - New Component - System Project名为swan选择创建的kv260_custom作为platform照常设置sysroot为cortexa72-cortexa53-xilinx-linuxsysroot toolchain为aarch64-xilinx-linux2.2 新建Vitis Application然后File - New Component - Application创建swan_host一路next记得设置sysroot为cortexa72-cortexa53-xilinx-linuxsysroot toolchain为aarch64-xilinx-linux。一直到add source这里加入所有非kernel的文件2.3 新建Vitis HLS然后是创建HLS component。同样是File - New Component - HLS。每个kernel_*.cpp文件都要创建一个对应的HLS kernel。这里拿kernel_matmul.cpp举例然后要跑C synthesis和package以上这个步骤需要再重复五次总共分别给swan_add, swan_matmul, swan_mul, swan_rmsnorm, swan_rope, swan_softmax.2.4 构建bitstream和host等六个kernel都完事回到swan主项目这里把他们添加进来然后Build Binary Container。我这里遇到了卡在xo文件生成完毕的情况猜测是因为没有在cfg文件中显示的指定xo文件可是我明明指定了....希望有大佬解惑。anyway通过命令行显式地指定xo文件可解# 在kv260_swan/swan下运行 v -l -t hw \ --platform ../kv260_custom/export/kv260_custom/kv260_custom.xpfm \ ../swan_add/kernel_add/kernel_add.xo \ ../swan_matmul/kernel_matmul/kernel_matmul.xo \ ../swan_mul/kernel_mul/kernel_mul.xo \ ../swan_rmsnorm/kernel_rmsnorm/kernel_rmsnorm.xo \ ../swan_rope/kernel_rope/kernel_rope.xo \ ../swan_softmax/kernel_softmax/kernel_softmax.xo \ -o build/hw/binary_container_1.xclbin \ --clock.default_freqhz 200000000 \ --save-temps --log_dir build/hw/logs --verbose最终应该会有这个xclbin文件然后build swan_host2.5 打包文件由于我没买网线只能靠U盘传输文件所以要把文件打包进一个swan_bundle:# 新建目标文件夹放到 kv260_swan 下 mkdir -p ~/Projects/KV260_Study/swan/kv260_swan/swan_bundle # 复制 pl.dtbo cp ~/Projects/KV260_Study/swan/kv260_swan/kv260_custom/export/kv260_custom/sw/boot/pl.dtbo \ ~/Projects/KV260_Study/swan/kv260_swan/swan_bundle/ # 复制并重命名 xclbin - binary_container_1.bin cp ~/Projects/KV260_Study/swan/kv260_swan/swan/build/hw/binary_container_1.xclbin \ ~/Projects/KV260_Study/swan/kv260_swan/swan_bundle/binary_container_1.bin # 复制 swan_host 可执行文件 cp ~/Projects/KV260_Study/swan/kv260_swan/swan_host/build/hw/swan_host \ ~/Projects/KV260_Study/swan/kv260_swan/swan_bundle/ # 复制模型文件 cp ~/Projects/KV260_Study/swan/model/stories15M.bin \ ~/Projects/KV260_Study/swan/kv260_swan/swan_bundle/model/ cp ~/Projects/KV260_Study/swan/model/tokenizer.bin \ ~/Projects/KV260_Study/swan/kv260_swan/swan_bundle/model/ # 生成 shell.json cat ~/Projects/KV260_Study/swan/kv260_swan/swan_bundle/shell.json EOF { shell_type : XRT_FLAT, num_slots: 1 } EOF # 查看打包结果 ls -lah ~/Projects/KV260_Study/swan/kv260_swan/swan_bundle一切顺利的话此时所有文件就都准备好了swan_hostbinary_container_1.binpl.dtbomodel/stories15M.binmodel/tokenizer.binshell.json3. 部署# 1) 新建目标应用目录 sudo mkdir -p /lib/firmware/xilinx/swan # 2) 进入 U 盘目录假设挂载点是 /media/ubuntu/0012-0CBA/swan_bundle cd /media/ubuntu/0012-0CBA/swan_bundle # 3) 把三件套复制到系统目录xmutil 只需要 dtbo/bin/json sudo cp pl.dtbo binary_container_1.bin shell.json /lib/firmware/xilinx/swan # 4) 可执行文件 swan_host 和 .bin 文件放到用户目录 cp swan_host ~ cp binary_container_1.bin ~ cd ~ # 5) 查看当前已注册的应用 sudo xmutil listapps # 6) 卸载旧的应用如果有 sudo xmutil unloadapp # 7) 加载新的 swan 应用 sudo xmutil loadapp swan # 8) 给予运行权限 chmod x ./swan_host # 9) 运行 ./swan_host最后运行的结果那么这就算是成功将一个迷你的语言模型部署在kv260上了不过吞吐量是原教程中的三分之一未来再尝试修复吧。写在后面这篇文章拼拼凑凑也许漏洞百出如果有大佬耐心阅读下来并发现了错误非常欢迎您在评论区指点。如果有未来的大佬看了这篇文章并觉得有帮助可以点一点大拇指鼓励一下作者但最重要的是将分享知识、分享经验的精神传递下去。