0. TL;DR
- DGX Spark 黑客松参赛项目
- 我们做了一台「活的音序器」:一棵树 = 5 条音高枝 × 16 步网格,鸟栖落决定起音、枝位决定音高、驻留决定时值,规则里没有一个音乐词汇,音乐从生态里长出来;
- 五个 LLM 智能体(Master + Pad/Melody/Bass/Jungle 四个 Flock)在同一套符号世界里协同作曲,全部跑在本地 DGX Spark的Step3-VL-10B上;
- 每个发声单元由自研 MIDI-BRAVE 神经合成器驱动:8D 控制坐标 → 128D 声学轨迹 → BRAVE 解码器,音高可控、音色可在潜空间连续漫游;
- 全端侧部署:五个 agent 决策 + 7 路神经音频解码共享一张 GB10,不依赖任何云端算力;
1. 缘起:为什么让鸟来作曲
- Jungle 音乐的文化谱系:Amen Break 的「切片—重排—反馈」精神,我们把它重构成一个可持续运行的多智能体音乐生态
- 核心直觉:传统音序器把音乐当时间轴上的格子,我们把音乐当有生命力的生态系统——生态关系本身就是作曲机制
- 团队:Twiddle AI——为 AI 音乐时代创造新的乐器和创作工作流;我们相信 AI 不应该只替人生成一首完成品,而应该成为人可以持续演奏、控制和共同创作的音乐系统(团队介绍见文末)
2. 总体架构:五层结构
- 生态仿真层:5 枝 × 16 步符号网格,1 天 = 4 小节 × 4 拍,昼夜循环 + 四季演化;
perch/unperch/dawn/dusk事件驱动;系统记住昨日状态,次日延续变异 - Agent 运行时层:Master 管时间/季节/和声/张力/速度(只从菜单选 intent),四个 Flock 各写各的声部,音乐泄漏隔离(Flock 只读无 MIDI 的生态投影)
- 音乐映射层:双链设计——符号链(栖落/枝位/驻留 → note/gate/duration)+ 连续链(8 维生态关系 → 音色坐标),两条链只在发声引擎汇合
- 音频合成层:MIDI BRAVE 神经合成器(详见 §5)
- 可视化与交互层:浏览器 5×16 网格交互、声部接管、潜空间漫游器、混音与录制
设计哲学:零音乐词汇规则,节奏与结构自发涌现;人可以随时进入生态、局部接管、再交还——系统从被改变的世界继续生长。
3. 五个智能体怎么养(Agent 工程实录)
3.1 分工与协同
- Master 只选 progression / color / tension / tempo intent;Flock 输出
dwellBeats / activeBars / holdLoops / cellMutations - 四个 Flock 合并一次推理请求,Flock 与 Master 并行;全部
json_schema约束输出,代码侧菜单校验 + clamp + 非法整包回退 - 调度:single-flight、按日退避、连续失败断路器;决策错过黎明就延后,绝不打断走带
3.2 部署:DGX Spark 单卡扛全部
vLLM 0.25.1(arm64)+ Step3-VL-10B INT4 AWQ(compressed-tensors),服务名
bird_agent@8081模型选型上必须夸一句阶跃星辰:Step3-VL-10B 是这个场景里难得的「甜区模型」——10B 体量单卡可承载多路并发,指令遵循和结构化输出能力却足以撑起五个角色的稳定决策;官方同时提供 FP8 与社区 INT4 多种精度,量化后 5 题精度抽查与 FP8 无可见差异,让我们能在算力和质量之间自由选点。对端侧多智能体应用来说,「够用、能并发、可量化」比「更大」重要得多
text-only 模式(
--limit-mm-per-prompt image=0):加载时跳过视觉塔,显存里的模型从 9.65 GiB 缩到 6.02 GiB——一行参数省出 3.6 GiB 给 KV cache性能:TTFT 50–90ms,单流 ~39 tok/s,16 并发聚合 ~620 tok/s;一次 JSON 决策(1300 tok 入 / 90 tok 出)实测 2.2–3.0s
3.3 小模型 agent 踩坑实录(全文最干的部分)
- json_object 大 state 被原样复读(锚定效应,改 prompt/few-shot 均无效)→ 一律
response_format=json_schema,顺带消灭了 10B 模型的长篇 CoT - 枚举字段放生成顺序首位会被第一条规则锚定→ 放 reason 之后
- 引导解码「空白跑路」:模型无限输出合法 JSON 空白 → xgrammar
disable_any_whitespace: true根治 - reason 啰嗦撑爆 max_tokens→
pattern限定字符集+长度(4~30 字);不要用maxLength硬截断——截断后会陷入无限空白循环 - 10B 模型数值阈值判断不可靠→ 运行时把阈值/几何判断预计算成布尔 flags,模型只做意图与策略
- 逐层回退:StepFun → 规则层(同一输入投影、同一安全菜单),LLM 挂了生态照跑
3.4 后端选型:四组实测对比
| 后端 | 单流 decode | 16 并发聚合 | 16 并发 TTFT p95 |
|---|---|---|---|
| vLLM + INT4 AWQ-CT(选用) | 37.6–39.3 tok/s | 617–624 tok/s | 126–128 ms |
| llama.cpp + Q4_K_M | 40.5–42.2 tok/s | 364–375 tok/s | 冷槽首请求抖动最高 16.6s |
| SGLang + FP8 | 17.9–18.1 tok/s | 316.0 tok/s | 108 ms |
| vLLM + FP8 | 17.7–17.9 tok/s | 304.5 tok/s | 168 ms |
多 agent = 简单决策 × 多路并发,正是 vLLM 连续批处理的甜区。权重格式坑:GGUF 不能上 vLLM;AutoAWQ 格式与 vLLM 加载器冲突(qkv 排除项);INT4 只有 compressed-tensors 可用。TensorRT-LLM / LMDeploy 不支持 Step3-VL,直接排除。
4. MIDI BRAVE:把音色变成一个可以走进去的空间
4.1 音色不是一个点,而是一条轨迹
传统音色模型把一个音色压成一个静态向量,结果是「音色正确但运动不真实」。MIDI BRAVE 把音色拆成三层:
8D 控制坐标(想要什么音色)
→ 128D 声学轨迹(音色如何随音符生命周期演化)
→ 条件式因果 BRAVE 解码器(44.1kHz 波形)
- gate / onset / release / velocity 显式进入轨迹生成器,动态包络是音色表示的一部分;
- MIDI 音高走独立分支,音高与音色解耦——同一条轨迹可以配任意 note;
- 四条独立模型(Pad / Lead / Bass / Pluck,各 50 anchor 共 200 音色),不共享权重与潜空间,同类内部才能插值。
4.2 生态驱动音色
8 维生态关系向量(栖驻/能量/换枝/邻群活动…)→ 固定投影 + 平滑 → 音色控制坐标;鸟群关系一变,坐标跟着动,解码器逐块生成新波形。自动漫游用 XY + kNN=4 限制在训练 anchor 凸包内,永远不会「漫游出车祸」。
4.3 数据与三阶段训练
- 数据:1,600 个候选音色 / 93,924 条片段 / 129.8 小时,标签证据 + CLAP 语义相似度 0.8/0.2 加权筛选,全局互斥分配,最终四类各 Top50(共 200 音色)。
- 训练目标:不是重建一段波形就完事,而是三层衔接——学会完整的 128D 动态轨迹(保留 ADSR、谐波演化)→ 学会可演奏的控制映射(8D 坐标 + velocity + 生命周期直接生成轨迹)→ 联合优化整条合成链路。
- 三阶段流程(Teacher 随机初始化,不复用外部权重,合计 32,217 次更新):
- Teacher:轨迹编码 + 音频重建;复合音频损失(STFT/多频带/包络/RMS)+ 一堆精心设计的约束——
pitch_adversary把音高信息挡在音色轨迹之外(解耦的关键)、trajectory_audio_usage用「静态均值反事实」逼模型真的去用动态轨迹、CLAP 当固定感知评审团(每 4 步算一次,省显存); - Distill:8D 控制接口蒸馏 Teacher 轨迹,损失对齐全帧点、一阶速度、二阶曲率、邻域几何——复制的是轨迹的「运动形态」而不只是位置;
- Joint:运行时轨迹直接接解码器端到端打磨。
- Teacher:轨迹编码 + 音频重建;复合音频损失(STFT/多频带/包络/RMS)+ 一堆精心设计的约束——
- 收敛实测(Pad 历史实验):Teacher 总 Loss ↓50.4%,Distill ↓94.3%(8D 控制确实逼近了 Teacher 轨迹),Joint 低起点再降 10.5%。
4.4 实时化:固定 7 行 Voice 池
- Spark 上
brave-voices固定 7 行(bass×1、lead×1、pluck×1、pad×4),pad 四行共享只读权重、独立 streaming state——真四音和弦,不重复占显存 - 固定池 +
gate=0常驻:避免动态 batch 导致跨块状态清零、声部爆音 - 持久 CUDA stream 跨行并行:七行满载 p50/p95 = 30.16/33.83ms,在 46.44ms 块预算内留 27% 余量
- WebSocket 推 float32 PCM → 浏览器 AudioWorklet;Jungle 声部用真实 Amen sample 颗粒切片
4.5 开发历程:8 天半,101 个 commit,三次大转折
MIDI BRAVE 不是在键盘前凭空设计出来的,是被一个又一个实验结论「逼」成现在这个样子的。以下全部来自仓库 git 历史(Latent-Cosmos-Synth,07-14 → 07-22,线性 101 commit):
Day 1(07-14):一天做出会出声的可玩世界。首个 commit 就是 46 文件 / 4682 行的完整骨架——产品哲学、boids 世界观、Web 应用、研究管线一次到位。当天 17 个 commit 连轴转:流式 BRAVE 解码器跑进浏览器,flock 直接当 voice 控制器。但 Phase 1 模型虽然在 qgpu 上训完了 100 万步,当天的收尾文档诚实地记了一笔:人耳听感关未过,6 声部硬实时仍有 deadline miss。能响,但还不能听。
Day 1–3(07-14 ~ 07-16):把生态和 latent 焊起来。boids 运动直接映射进 BRAVE latent、flock 空间驱动复音 decoder 合奏、由 flock 关系驱动神经音色——「生态 → 潜空间」这条核心链路,是这三天打通的。
Day 7(07-20):存量训练框架入库,四模型时代。前期在 V100 集群上完成的 MIDI 条件 BRAVE 训练框架整体并入(一次 208 文件 / 2.46 万行):四模型各训 7 小时 16 分、越过 40k/100k updates,MIDI 音高约束已学会(cross pitch 0.04–0.08),但 CLAP 目标最不确定——这个「不确定」是下一场转折的伏笔。
Day 7 下午(07-20):第一次大转折——砍掉 encoder,转向预测式生成。此前的路线是「真实音频过 encoder 拿 latent」;新的设计文档明确:部署模型不接收音频、不含 encoder。训练期用 encoder 产出真值 latent,部署时从 seed bank 取历史,由一个因果 TCN 多步预测器持续「滚」出未来 latent,CLAP 与 MIDI 条件共同驱动 decoder。当天下午方向确定,当晚完成实现:因果 encoder → 多 horizon 预测器 → 四阶段训练 → encoder-free TorchScript 导出,一天之内完成转身。
Day 8(07-21,35 个 commit,最密的一天):第二次大转折——重建好 ≠ 可控。评测把问题暴露得很残酷:解析式 MIDI swap loss 降到 ~0.09,但外部 MIDI 跟随率只有68.75%;CLAP 条件可以被 z_rave 里的音色信息「走捷径」满足——重建保住了,音高和音色却不受控。解法是一整套反事实(counterfactual)训练范式:MIDI-only 组加源音高排斥,timbre-only 组用冻结 CLAP 的波形梯度把音色拉向目标、推离源音色,让音高与音色变成「独立可控」而不只是「有响应」。同日还爆发了非有限值危机:罕见 NaN 出现在 CLAP embedding 里,团队从容忍 → 诊断 → 逐级 trace → DDP 全局拒绝非有限更新,连着 8 个 commit 把数值稳定性钉死。
Day 9(07-22):第三次转折——从能训练到能演奏。Phase 3 联合 rollout、训练基础设施迁移 A800 集群、试听台闭环(3 seed × 4 音色 × 4 音高 = 48 个 clip,缺一个或出现非有限音频即 fail)。HEAD 停在最后一个 plan 上:本地实时 latent 乐器——WebSocket 服务每次step()出 512 个样本(11.61ms),在 PCA 二维基上连续漫游 CLAP 音色空间,验收标准是30 秒零 underrun、推理 p95 < 11.61ms。这正好就是黑客松现场brave-voices7 行 voice 池的前身。
回头看,三个最关键的工程判断都是「被数据逼着做的」:encoder-free 是部署形态逼的、反事实训练是跟随率 68.75% 逼的、固定 voice 池是 deadline miss 逼的。
5. DGX Spark 平台实战笔记
一台桌面设备装下整个乐队:GB10(Grace Blackwell,aarch64 / sm_121 / CUDA 13)单卡同时承载 LLM 推理 + 7 路神经音频解码 + 生态仿真。这在一台传统工作站上几乎不可想象——LLM 要常驻显存、KV cache 要随并发伸缩、神经解码器要按 46.44ms 的块时钟准时交付,任何一环抢不到资源,要么决策迟到、要么声音破音。DGX Spark 的128 GB 统一内存是破局关键:CPU 与 GPU 共享同一物理内存,LLM 权重、KV 池、四套 BRAVE 模型、PCM 缓冲全部放进同一个地址空间按需划分,不用在「显存墙」前做痛苦的二选一;配合最高 1 PFLOP FP4 的算力,INT4 量化的 10B 模型跑出 620 tok/s 聚合吞吐的同时,7 路神经解码还能在块预算内留 27% 余量。这几天有一些朋友来访,他们看到这个项目,最常问到的问题是「云端在哪」——答案是没有云端:五个智能体的决策、全部声音的生成都发生在这台摆在桌面上的设备里,断电即带走。这就是 DGX Spark 这类桌面 AI 超算对实时生成系统的意义:以前需要一间机房才能同时供起来的「大模型 + 实时神经渲染」,现在一台设备就是全部基础设施
nvidia-smi 在 GB10 上显存字段不可用 → 容器内
torch.cuda.mem_get_info();看负载用功率(idle ~10.8W,推理 30–38W)vLLM 常驻显存是
--gpu-memory-utilization预分配 KV 池的设计行为,不是泄漏;从 0.80 调到 0.575,给神经合成预留 ~30 GiBn-gram 投机解码实测:草稿命中率 88%、单请求 2.4s→1.1~1.4s,但 16 并发吞吐 −16% 且与 json_schema 组合触发空白循环——生产不启用,优先正确性
LLM × 神经音频的算力调度:两者共享一张卡,请求撞车时调度层立刻让 Agent 推理让出算力(不释放显存、可恢复),优先保音频块按时交付——决策错过黎明可以顺延到明天,声音断了就是事故
6. 附录
- 开源仓库: https://github.com/Twiddle-AI-China/intelligent_jungle
- 参考资料:
RAVE:https://arxiv.org/pdf/2111.05011v2.pdf
CLAP: https://arxiv.org/pdf/2211.06687.pdf
Modelscope技术报告:https://modelscope.cn/models/stepfun-ai/Step3-VL-10B-Base
7. 关于我们:Twiddle AI
Twiddle AI,为 AI 音乐时代创造新的乐器和创作工作流。
我们相信,AI 不应该只替人生成一首完成品,而应该成为人可以持续演奏、控制和共同创作的音乐系统。Twiddle AI 聚焦 AI 乐器、实时音乐交互与智能音频技术,通过硬件、软件和生成模型的结合,把语音、手势、演奏和音乐生成连接成一套可控、可编辑、可实时反馈的创作工作流。我们的产品既降低音乐创作与演奏的门槛,也为音乐人提供新的声音设计、灵感捕捉和人机协作方式,让 AI 从后台的生成工具,变成可以亲手参与、实时交流的乐器与创作伙伴。