用Agent搭建QEMU RISC-V AI芯片实验台的实操指南
提到“用AGENT做QEMU环境搭建拉起一块RISC-V AI芯片的实验台”很多人第一反应是QEMU模拟器我熟Agent我也熟但它俩怎么凑到一块儿说实话这个组合第一次出现在我面前的时侯我也愣了一下。后来我仔细想了一下需求场景发现这里面的逻辑其实很顺——你想要研究RISC-V架构的AI芯片但手里没有真实芯片甚至只是想在芯片流片之前先把软件栈跑起来同时你又不想花一整个下午去啃文档、敲命令、查报错。这时候让Agent帮你把QEMU这套模拟环境搭起来本质上就是一场“人提需求、Agent干脏活、人来验收”的协作实验。这篇文章我会完整讲一遍我实际操作的思路和过程为什么要在QEMU里模拟RISC-V AI芯片、Agent在这个任务里到底该承担多少工作、QEMU的关键配置怎么落地、AI芯片外设怎么挂、以及Agent最容易在哪几个环节翻车、怎么把坑填上。整个过程是基于我最近一次从零搭建的可复现路径不是纯粹讲概念适合两类人看一类是刚接触RISC-V和QEMU的开发者想找一条省力的上手路另一类是已经在折腾AI Agent的玩家想看看Agent在真实系统级任务里能做到什么程度、需要人兜底的地方在哪里。1. 为什么非要在模拟器里折腾一块“RISC-V AI芯片”先说动因。我最近在评估几颗RISC-V架构的AI加速芯片其中一颗主控是RISC-V 64位核心外挂NPU模块跑一些轻量级视觉模型。按理说最直接的验证方式是拿开发板跑但问题来了开发板要申请、要等驱动和编译器工具链的版本又跟官方SDK绑死更麻烦的是芯片还在改版寄存器手册每两周更新一次硬件到手的时候软件可能已经过时了。所以在真实硬件到位之前最靠谱的方案就是用QEMU先把指令集环境和外设框架模拟出来。QEMU对RISC-V的支持已经相当成熟它能把virt机器模型跑起来支持SMP多核、中断控制器PLIC、virtio设备还有RISC-V向量扩展(RVV)的TCG模拟。什么意思呢就是虽然没有芯片但你可以在模拟器里编译运行一段RISC-V指令的AI推理程序验证交叉编译工具链、链接脚本、内存布局、runtime调用链这些纯软件层面的东西。等真芯片出来后绝大多数代码只需要换一块目标板重新编译就能跑。用Agent来做这件事的动机就更直接了。QEMU搭建环境本身是一个“文档密集型”任务——要查的参数很多机器模型选virt还是spike、CPU选rv64还是rv64gc、内存映射的起始地址、设备树的生成方式、内核镜像用什么格式、网络用user模式还是tap模式。新手查这些文档至少要折腾大半天就算老手也经常因为某个版本行为差异卡住。而Agent恰恰擅长做这种“信息检索命令生成根据报错迭代”的事情把以前需要人反复查文档、试命令的体力活承包掉了。这里要强调一句Agent不是替你思考而是替你把“已知路径上的重复劳动”提速。我给自己定的目标是——让Agent去查参数、写启动脚本、配网络、装依赖我负责定方向、验结果、处理Agent解决不了的逻辑盲区。这样搭出来的环境既有模拟器的严谨性又有AI辅助开发的效率。整个架构理清楚之后我按下面的任务清单推进后面每个环节都会展开讲。2. 这一步棋的关键把“搭环境”拆成Agent能接得住的子任务Agent这东西有个老毛病任务给得太大太含糊它就开始一本正经地胡说八道。如果你一上来就丢一句“帮我搭一个QEMU的RISC-V AI芯片环境”它大概率会给你生成一串看起来很完整的脚本实际上漏洞百出——因为“RISC-V AI芯片环境”这个词的粒度太大不同芯片、不同SDK、不同外设模型对应的配置千差万别Agent无法判断你的真实意图。所以我做的第一件事不是写配置而是把总目标拆解成一个“任务树”。拆解的原则是每个子任务必须有一个明确的验收标准Agent可以在终端里执行命令并自行确认结果。下面是我在实际操作中用的拆解结构你可以直接参考安装QEMU并确认qemu-system-riscv64可用下载或编译RISC-V 64位Linux内核镜像或直接使用发行版提供的镜像准备根文件系统rootfs能登录并能安装软件包用-machine virt启动QEMU验证串口输出和系统启动配置网络user模式网络或tap0桥接验证能访问外网挂载宿主机目录9p virtfs方便代码互传在guest里安装AI推理依赖Python、ONNX Runtime或TFLite跑通一个RISC-V向量指令的推理样例作为“AI芯片可用”的验收信号这8步每步之间都有明确的依赖关系第1步不完成后面全是空谈第4步不通过第5步之后无从谈起。把任务拆到这个粒度之后Agent每次只需要执行一小段命令、观察一个明确的输出结果出错时也容易定位是命令写错了还是环境本身有问题。拆解之后开始选Agent的干活形态。目前主流的做法有两种一种是让Agent直接接管终端通过工具调用执行命令并读取输出自动迭代。这种适合它独立完成“下载、解压、编译、启动、看日志”这类闭环操作。另一种是Agent只做“顾问”——你提问它给命令和解释你手动执行。这种更安全但效率打折。我实际用的是混合模式第1到第4步让Agent在终端里反复尝试遇到报错它自己改命令重试第5到第8步因为涉及网络配置和交叉编译链的细节我让Agent先生成方案我再确认后执行。为什么要这样分工因为前几步是“只要愿意试就能试出来”的确定性任务模型的试错能力在这里是加分项后面几步是“方案选错会浪费大量时间”的设计性任务必须人来定方向。还有一个重要的点是给Agent的上下文里要带上环境约束。我的做法是让它先执行几条命令探测宿主机的CPU架构、QEMU版本、网络环境然后再给它下任务。比如宿主机是x86_64guest是riscv64这就要区分模拟器二进制和交叉编译器如果你的宿主机本身就是ARM那有些步骤会简化很多。这些信息如果你不主动喂给Agent它很容易默认按x86环境处理生成一些在ARM和RISC-V之间混淆的命令。下面这张表是我在任务拆解阶段给Agent建的验收清单子任务验收命令期望结果QEMU安装qemu-system-riscv64 --version显示版本号且支持RISC-V内核启动qemu-system-riscv64 ... -kernel vmlinuz串口输出Linux启动日志最终出现login提示网络可用ip addr show eth0eth0有IP地址外部访问ping -c 3 mirrors.ubuntu.com丢包率正常或有DNS解析目录共享ls /mnt/shared能看到宿主机目录内容AI依赖就绪python3 -c import onnxruntime无报错向量指令可用运行RVV样例打印正确计算结果这个表格我建议你也在自己的项目里保留。Agent干完一个子任务你可以拿验收命令快速验证比自己翻日志高效得多。更重要的是这个清单本身就是给Agent的“完成定义”——它知道自己干到什么程度才算完不会中途撂挑子。3. QEMU本体从安装到启动离RISC-V系统跑起来最近的一条路说实话QEMU这套东西配置项特别多但核心链路并不复杂。你只需要记住一句话QEMU模拟的是整台机器包括CPU、内存、总线、外设你要给它一个机器模型、一颗虚拟CPU、一段内存、一种启动方式剩下的就是各种可选项。对我这个“RISC-V AI芯片实验台”的需求来说关键点是CPU要选带向量扩展的RISC-V核心机器模型要选带设备树和virtio支持的virt。3.1 安装QEMU的版本陷阱第一步安装就藏着坑。很多Linux发行版自带的QEMU比较旧比如Ubuntu 20.04上的QEMU 4.2对RISC-V向量扩展(RVV 1.0)的支持就很有限。我一开始用系统自带的包管理工具装的QEMU启动时虽然能跑但之后想模拟带V扩展的CPU就报“property v not found”——这个报错跟命令本身没关系纯粹是版本太老。所以我后面直接改成源码编译最新稳定版。编译过程不复杂但依赖要装全否则编译到一半报缺库很烦。以下是我在Ubuntu宿主机上的操作sudo apt install ninja-build build-essential libglib2.0-dev libpixman-1-dev zlib1g-dev python3-venv wget https://download.qemu.org/qemu-8.2.0.tar.xz tar xf qemu-8.2.0.tar.xz cd qemu-8.2.0 ./configure --target-listriscv64-softmmu --prefix/opt/qemu make -j$(nproc) sudo make install注意--target-listriscv64-softmmu这个参数它让编译只针对RISC-V的系统级模拟目标能省下大量编译时间。你要是把所有架构都编一遍机器差的话可能要等一个小时。编译完成之后执行/opt/qemu/bin/qemu-system-riscv64 --version看到版本号就说明这步到位了。这里有一个容易忽略的细节如果你之后还要用QEMU调试Linux内核比如配合GDB做vmlinux的单步调试编译时最好加上--enable-debug这样QEMU自身的GDB stub功能会更完善。实验台场景下建议加上成本很低但之后排障会爽很多。3.2 内核、rootfs、启动参数三件套缺一不可QEMU只是个硬件模拟器它本身不带操作系统。要让guest系统跑起来你需要准备内核镜像vmlinuz或Image格式、根文件系统rootfs、以及启动参数。这一步网上资料很多但也很杂最容易踩的坑是“内核镜像格式不匹配”——QEMU的-kernel参数对RISC-V来说接受的是Image格式扁平二进制而很多教程里让你用vmlinuz压缩格式结果直接起不来。我用的方案是下载Ubuntu官方提供的RISC-V 64位镜像包。你不需要自己编内核除非你想定制内核配置比如把RVV向量支持编进内核的ISA字符串里。下载地址是Ubuntu ports镜像里的riscv64目录正常情况下会包含vmlinuz和rootfs相关的软件包。如果你懒得去翻镜像站也可以直接用Buildroot生成一个最小系统但对实验台场景来说Ubuntu生态更友好包管理器能帮你省一堆事。启动命令的骨架是/opt/qemu/bin/qemu-system-riscv64 \ -machine virt \ -cpu rv64,vtrue,vlen128,elen64 \ -smp 4 \ -m 8G \ -kernel vmlinuz-riscv64 \ -append root/dev/vda1 rw consolettyS0 \ -drive filerootfs.img,formatraw,idhd0 \ -device virtio-blk-device,drivehd0 \ -nographic逐项解释一下这些参数因为它们是这个实验台的核心地基-machine virt指定机器模型。virt是QEMU对RISC-V的通用虚拟开发板支持virtio设备、PLIC中断控制器和设备树适合跑Linux。-cpu rv64,vtrue,vlen128,elen64指定CPU核心为64位RISC-Vvtrue表示开启向量扩展vlen128是向量寄存器长度elen64是元素宽度上限。这一步对“AI芯片”实验台至关重要因为NPU加速的软件栈往往会用到RVV指令做预处理。-smp 4分配4个虚拟CPU核。AI推理任务偶尔会开多线程4核跑起来比较接近真实板子的体感。-m 8G给8GB内存。这个容量对轻量级模型足够也贴近低功耗AI芯片DDR配置的常规范围。-kernel和-append指定内核和启动参数。consolettyS0把控制台输出重定向到串口这样-nographic模式下你能直接在终端看到启动日志。-drive和-device virtio-blk-device把rootfs块设备挂成virtio磁盘。virtio在QEMU里性能好guest里面不用额外装驱动内核自带。第一次执行这条命令后你会在终端里看到密密麻麻的Linux启动日志最后停在login:提示符处。到这里一个基础RISC-V系统就算跑起来了。3.3 网络怎么通从user模式到tap0桥接系统跑起来只是第一步实验台必须要能联网否则后面装Python包、交叉编译工具全部抓瞎。QEMU的网络有两档选择user模式网络-netdev user最省事guest里自动拿到10.0.2.x的IP但它有个硬限制外部网络无法主动连接guest且部分ICMP协议比如ping包的某些类型支持不好。对“装上环境、跑推理”来说user模式通常够用但它不适合做需要外部调试器连入guest的场景。我这次为了模拟更接近“真实芯片通过以太网连到开发机”的形态用了tap0桥接模式。做法是在宿主机上建一个虚拟网桥让QEMU的网卡通过tap设备接入桥里这样guest和宿主机在同一个二层网络里IP可以互访。具体流程# 在宿主机创建TAP设备 sudo ip tuntap add dev tap0 mode tap user $(whoami) sudo ip addr add 192.168.100.1/24 dev tap0 sudo ip link set tap0 up # 启动QEMU时挂上tap0 qemu-system-riscv64 ... \ -netdev tap,idnet0,ifnametap0,scriptno,downscriptno \ -device virtio-net-device,netdevnet0,mac52:54:00:12:34:56进guest之后手动给eth0配IPip addr add 192.168.100.2/24 dev eth0 ip link set eth0 up ip route add default via 192.168.100.1这个方案有个很实用的小技巧如果guest需要访问外网把宿主机上的IP转发打开再在宿主机上配一条SNAT规则guest里的流量就能通过宿主机上网了。命令如下# 宿主机开启IP转发 sudo sysctl -w net.ipv4.ip_forward1 # 将guest的流量做SNAT转发到宿主机外网网卡 sudo iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o eth0 -j MASQUERADE到这里guest的DNS、apt源就全通了。你可以在guest里做apt update装东西不再受限。如果你搞不定网络也完全不必死磕tap0user模式下的端口转发一样能把guest的SSH服务映射出来-netdev user,idnet0,hostfwdtcp::2222-:22然后用ssh -p 2222 userlocalhost直接登进guest不需要配IP。这种方式在做AI推理验证时也挺顺手因为你可以把代码用scp直接推上去。4. 给“AI芯片”搭台子向量指令、推理运行库、外设模拟三件事基础系统有了网络通了接下来就是这篇文章最核心的部分——怎么让这个QEMU环境看起来像一块“AI芯片实验台”。这里要说清楚一个现实QEMU不是芯片原厂出的那种专用模拟器它不可能精确模拟某颗NPU的寄存器级行为。所以“AI芯片实验台”在QEMU里的合理含义是模拟出AI芯片的通用计算特征RISC-V向量扩展、多核、DDR布局在上面跑AI推理的软件栈验证部署流程和性能基线。4.1 第一个信号RVV向量指令能不能跑起来AI计算和普通程序的差异之一是大量使用向量指令。RISC-V的向量扩展(RVV)就是这个架构体系的SIMD方案。对实验台来说首先要确认QEMU里的CPU真的支持RVV并且在用户态程序里能正确执行。一个最简单的验证程序是向量加法。在guest里用C写一小段代码用RVV intrinsic编译执行#include riscv_vector.h #include stdio.h int main() { float a[8] {1,2,3,4,5,6,7,8}; float b[8] {1,1,1,1,1,1,1,1}; float c[8] {0}; size_t vl vsetvlmax_e32m1(); vfloat32m1_t va vle32_v_f32m1(a, vl); vfloat32m1_t vb vle32_v_f32m1(b, vl); vfloat32m1_t vc vfadd_vv_f32m1(va, vb, vl); vse32_v_f32m1(c, vc, vl); for (int i 0; i 8; i) printf(%.0f , c[i]); printf(\n); return 0; }编译时加-marchrv64gcv启用向量指令集gcc -marchrv64gcv -O2 -o rvv_test rvv_test.c ./rvv_test输出2 3 4 5 6 7 8 9就说明RVV指令在你的实验台上真实可用了。这一步的价值在于之后你要跑的任何AI算子只要是基于RVV向量化的都能在这个环境里验证行为和数值正确性。到这里要提醒一句你必须在启动QEMU时通过-cpu参数启用了vtrue否则编译出来的RVV程序执行时会报非法指令错误。这个错误在QEMU里表现得很隐蔽——直接Segmentation fault不是像真实硬件那样触发SIGILL并打印明确的指令信息。我第一次就被这个坑卡了半小时。4.2 推理运行库怎么进guestONNX Runtime还是TFLiteAI芯片实验台除了指令集还要有推理框架。这个选择我纠结过一阵在RISC-V模拟器里装PyTorch不太现实因为PyTorch对RISC-V的支持还在早期编译耗时长、依赖巨多而ONNX Runtime官方提供了RISC-V后端虽然没有像x86那样开箱即用但源码编译的路径是通的TFLite Micro则更轻量适合MCU级的AI芯片场景。我的选择是双轨先装ONNX Runtime做模型推理验证再装一个TFLite Micro的demo作为边缘场景参考。ONNX Runtime在RISC-V架构上编译的步骤比较长但不用全量编译只需要编CPU执行提供程序的部分。关键配置是git clone --recursive https://github.com/microsoft/onnxruntime.git cd onnxruntime ./build.sh --config Release --build_shared_lib --skip_tests \ --cmake_extra_defines CMAKE_SYSTEM_PROCESSORriscv64这个编译过程我的环境里耗时约40分钟4核QEMU guest。编出来的libonnxruntime.so复制到系统库目录后在guest里跑一个小模型做推理验证比如加载一个MobileNet量化模型输入一张随机图拿softmax结果看类别索引是否合理。这一步只要输出数值正常、程序不崩溃实验台的AI推理链路就算是打通了。如果ONNX Runtime编译太慢有一个更轻量的验证方案用C直接调用RVV intrinsic手写一个3x3卷积算子在guest里跑一段推理逻辑。它能验证编译器、运行库、内存访问模式的正确性虽然慢但对“实验台”来说足够验证软件栈了。速度要有个预期QEMU的TCG是动态二进制翻译执行性能通常比真实硬件慢10到30倍所以别指望在上面跑实时推理它的定位是“验证正确性”而不是“评估性能”。4.3 QEMU里的“NPU外设”设备树、寄存器模型与DISCRETE设备到这里就要触及“芯片外设”这个有意思的话题了。很多人问我QEMU里能不能模拟一颗NPU能但要看你怎么定义“模拟”。如果你要的是“能响应寄存器读写、能触发中断、能与主核交互”的外设模型那QEMU支持你写一个自定义device。QEMU提供了一套C语言接口来描述设备包括寄存器读写回调、MMIO映射、中断引脚等。你可以在hw/misc目录下做一个简单的edu设备或自己写的npu-device。它的行为完全由你定义——比如你定义某个寄存器为“启动推理”另一个寄存器为“读结果”然后让它在QEMU里完成一个假的矩阵运算。这种方式的价值是你可以提前写好Linux驱动验证驱动和主核之间的握手逻辑等真芯片的寄存器手册确定后改改偏移量就能复用绝大部分驱动代码。下面是一个最简的QEMU设备模型骨架C语言核心是注册MMIO区域和读写回调static uint64_t npu_read(void *opaque, hwaddr offset, unsigned size) { switch (offset) { case NPU_STATUS: return 0x1; // 表示idle case NPU_VERSION: return 0x20240601; default: return 0; } } static void npu_write(void *opaque, hwaddr offset, uint64_t value, unsigned size) { if (offset NPU_START) { // 在这里模拟“启动推理”动作 // 可以触发一次qemu_irq_pulse()中断 } } static void npu_realize(DeviceState *dev, Error **errp) { NpuState *s NPU_DEVICE(dev); memory_region_init_io(s-iomem, OBJECT(s), npu_ops, s, npu-regs, NPU_MMIO_SIZE); sysbus_init_mmio(SYS_BUS_DEVICE(dev), s-iomem); sysbus_init_irq(SYS_BUS_DEVICE(dev), s-irq); }这个设备模型里我故意只做了“状态寄存器和启动触发器”目的就是让驱动的加载和中断处理能够跑通。然后启动QEMU时通过-device npu-device把它挂到总线上guest里的Linux就能通过设备树看到这个设备。你要在设备树源文件里加一个节点npu10000000 { compatible example,npu; reg 0x0 0x10000000 0x0 0x1000; interrupts 17; interrupt-parent plic; };设备树编好后guest里Linux启动时会在/proc/device-tree下看到这个节点。随后你写一个最简驱动模块加载时ioremap这段MMIO地址读一下NPU_VERSION寄存器这样“主核访问NPU外设”的完整路径就闭环了。这套做法听起来很硬核但它的核心价值并不在于“把假NPU驱动写得多完善”而是在于让你真正理解设备模型到底是怎么一回事。当我第一次在QEMU里看到自己写的Linux驱动成功读到自定义设备的版本寄存器时那种感觉不是跑通一个Python脚本能比的。不过如果你的目标偏应用层部署模型、验证推理库不打算折腾内核驱动那外设模型可以往后放一放。先跑通RVV向量指令加上推理库已经足够支撑一个“AI芯片开发环境”的日常使用。设备级模拟属于锦上添花等你有明确驱动开发需求时再投入研究完全不迟。5. Agent干活实录它在哪几步翻了车、我如何兜底前面讲的都是环境本身现在回到文章标题里的“用AGENT”这个核心。这一章我专门讲实操中Agent的表现——不是吹它多厉害而是如实记录它容易在哪几步翻车人应该怎么接管。5.1 第一类典型错误Agent瞎编版本号和路径我在让Agent下载内核时遇到一个典型问题。它直接给我一条命令去拉一个不存在的Ubuntu RISC-V内核包路径文件名版本号对不上。Agent说“已下载完成”但我一查文件大小只有几百字节其实是404页面被存了下来。这种问题的根源是Agent无法感知到当前的网络资源和镜像站实时结构它训练数据里的文件名和现在镜像站上的文件名有时间差。我处理的办法是在Agent执行下载命令后强制它运行一条校验命令file vmlinuz-riscv64 ls -lh vmlinuz-riscv64file输出显示Linux kernel ARM64 boot executable Image或者LSB executable这类格式才说明下载成功如果显示HTML document那一定是下载到错误页面了。要求Agent把这两条命令的输出贴回来确认无误再继续下一步。这也是为什么我在第二节强调“验收命令”那么重要。Agent自己说的“完成”很多时候是逻辑闭环的自洽而不是系统的真实状态。唯一的裁决标准是命令输出。5.2 第二类典型错误安装包名张冠李戴Agent给我生成一条安装命令把qemu-system-riscv64说成是软件包qemu-system-misc里的一个子命令。这个说法在部分发行版里其实没错有些打包把多个架构的QEMU合在一起但具体到我的环境源码编译的QEMU安装在/opt/qemu/bin并不存在这个包Agent显然没有把“我已经源码编译安装了”这个先验信息纳入考虑。这类错误比第一类更难防因为它不算“编造”而是“路径混用”。Agent倾向于从它训练数据里最普遍的配置出发给出答案而不是你当前的具体环境。我的解法是在启动Agent之前让它执行三条环境探测命令并把结果固定在对话上下文里uname -a which qemu-system-riscv64 /opt/qemu/bin/qemu-system-riscv64 --version | head -1在后续对话中如果Agent给出的命令和你环境里探测到的路径冲突你可以直接提醒它“我这边是源码编译的版本在/opt/qemu/bin下”它能很快纠正。5.3 第三类典型错误死循环式重试在配置网络tap0的时候Agent一度陷入死循环guest里ping不通宿主机它反复尝试同一个命令每次失败后改个IP地址段再试。其实问题根本不在guest而是宿主机上的iptables规则没有生效。Agent不会“跳出当前层面”去看问题——它只会不停调整guest侧的IP因为它已经默认“宿主机配置正确”了。我在这一步的介入点是让Agent停下来把问题重新审视一遍并且给出“如果三次重试仍失败则输出一份排查日志并由人介入”的指令。这相当于给Agent加了一个“熔断机制”。你也可以在Agent的system prompt里显式声明同一个错误连续出现三次就停止操作、总结输出让用户决策。这个约束能让Agent从“无限重试”中退出来把思考空间交还给人脑。下面是我实际用的一套Agent任务约束模板供参考1. 在执行任何破坏性命令删除文件、修改网络配置之前必须解释该命令的作用。 2. 下载类命令执行后必须用 file/ls 验证文件真实性。 3. 连续三次尝试同样操作失败后停止并汇报当前完整日志。 4. 每当出现错误时先提取关键报错行再修改命令禁止猜测性修改。 5. 对任何“已完成”的结论必须附上对应的命令行输出作为证据。这套约束看起来简单但对Agent的行为约束效果非常明显。加了之后它在第四步、第五步的错误率降低了不少因为“猜测性修改命令”被禁止了它每次都必须先分析报错再动手。5.4 Agent真正无可替代的地方从文档碎片里提取可行命令说完翻车的地方也得说说Agent真正“值钱”的地方。在搭建QEMU环境时有一件事极其耗时把官方文档、邮件列表、论坛帖子里碎片化的信息整合成一条可运行的完整命令。比如RVV的QEMU参数不同版本之间的行为差异、设备树里PLIC中断号分配规则、buildroot和Ubuntu镜像之间的格式差异——这些信息分散在几十个页面里手动搜的话没有大半天找不全。Agent在这件事上的表现让我比较意外。它能很快把散落的参数聚合到一个启动脚本里并且对每个参数给出出处说明我按它的脚本改改路径就能跑。这种“跨文档整合”加上“按语境生成配置”的能力确实比搜索引擎人工阅读的效率高出一个量级。这个体验也让我更确信了自己的分工方式Agent负责把碎片拼成整块我负责判断整块是否符合当前环境的约束。6. 跑通AI推理全链路从一颗“假芯片”到一个能出结果的实验台最后把这套环境从头到尾串联一遍讲清楚“实验台”到底能干什么。这个环节我把它叫“全链路验收”——不是只跑一个hello world而是跑一段真实的小型推理流程用最终结果说话。6.1 guest内搭建Python与推理环境有网络之后guest里装东西就简单了。Ubuntu的RISC-V移植版已经提供了比较完整的Python 3.10环境直接用apt安装pip然后用venv隔离环境apt update apt install -y python3-pip python3-venv git build-essential python3 -m venv /opt/ai-env source /opt/ai-env/bin/activate pip install onnxruntime如果在pip install onnxruntime这一步遇到“找不到匹配的wheel”的报错说明PyPI暂时没有riscv64的预编译包这时候需要从源码编译或者换用我前面提到的TFLite Micro方案。在模拟器里耐心一点这个情况是正常的不代表环境有问题。6.2 用RVV算子库跑一次真实的推理为了让“AI芯片”这个说法有说服力我建议你在guest里跑一个基于RVV的算子级推理demo而不是直接调大模型。这里分享一个我自己用的最小验证方案写一个两层卷积网络卷积核用RVV intrinsic实现输入用随机数据跑10次前向输出分类分数。这个demo虽然简单但它覆盖了AI推理最核心的两件事数据在内存中的布局NCHW、算子层向量化计算。伪代码逻辑是这样的// 对输入图像的每个输出通道做3x3卷积每次读一行数据 // 用vle32_v_f32m1加载9个像素 // 用vfmacc_vf_f32m1做乘累加 // 用vse32_v_f32m1写回输出feature map跑完输出结果后你会看到充沛的向量指令在QEMU里被执行量化精度和浮点误差都在预期范围内。这时你就可以理直气壮地说这块“RISC-V AI芯片实验台”已经能跑推理算法了算法层的代码可以直接移植到未来真实芯片的SDK里。6.3 性能参考与预期管理在QEMU里做AI推理性能这件事我要实话实说非常慢。我实测跑MobileNet量化模型单次推理耗时在QEMU里大概是真机的20倍以上。因为TCG翻译执行本身有巨大开销加上向量指令的翻译优化还不够成熟。所以实验台的定位非常明确验证软件正确性、部署流程、数值精度预研驱动开发和中断交互逻辑跑CI回归测试确保代码在RISC-V目标上不挂给编译器工具链做验证。不适合做的是性能评测、实时推理、训练任务。这些必须等真实硬件回来之后再做。但这个话反过来说也成立正因为QEMU慢你写代码时会更在意算法复杂度和内存访问效率这种“约束倒逼优化”在实验台阶段其实是好事。6.4 把这个实验台变成长期可用的开发设施环境搭好之后我建议你把启动命令、rootfs、内核镜像、hostfwd/tap配置都整理成一个项目目录并且写一个Makefile或者shell脚本实现一条命令启动、一条命令销毁。我在自己项目里是这样组织的riscv-ai-lab/ ├── qemu-system-riscv64 ├── vmlinuz-riscv64 ├── rootfs.img ├── start-lab.sh ├── stop-lab.sh ├── shared/ # 9p共享目录和guest的/mnt/shared对应 └── guest-setup.sh # 放进shared目录guest里一键执行AI环境安装start-lab.sh的核心就是一条QEMU命令的封装我把所有参数写进脚本以后每天启动只需要跑它就行。同时还可以在脚本背后加一个功能用-snapshot模式启动让guest对rootfs的写入不落盘方便做实验前后“一键还原”。这个技巧对反复折腾配置的场景尤其好用rootfs被搞坏了就重启不用重新刷。每次启动后我让guest开机脚本自动执行/mnt/shared/guest-setup.sh把Python环境、推理库、demo样例都准备好。这样整个实验台从“启动到能跑推理”只需要一次命令非常接近真实开发板的体验。如果你也给Agent下一阶段任务直接让它把环境状态核对一遍即可。最后的体会这套流程走下来我对“用Agent做环境搭建”这件事的看法是它确实能把搭建时间压缩一半以上但你得学会给它划边界、定验收、做熔断。Agent适合处理的是“路径明确、信息分散、需要大量命令试错”的任务QEMU环境搭建恰好符合这个特征。但在设备树定制、网络拓扑设计、外设行为定义这些“需要理解体系结构”的环节人的判断依然不可替代。如果你也想搭一个类似的RISC-V AI芯片实验台我建议你按这个顺序动手先不碰Agent手动跑通一遍QEMU启动流程理解每个参数的含义然后再让Agent参与你会发现它的错误率大幅下降因为你已经能准确判断它哪句话靠谱、哪句话需要纠正。反过来如果你一上来就把整件事交给Agent大概率会被它的“一本正经”带偏。最后再分享一个小技巧QEMU挂9p共享目录的时候记得加上-virtfs local,path/host/path,mount_tagshared,security_modelnone,idsharedsecurity_model选none是为了避免权限问题否则guest里写入共享目录的文件经常遇到权限拒绝。这个细节我折腾了一下午才搞明白提前说出来能帮你省下不少时间。