aMuseMe: When Small Models Compose a Visual Symphony

aMuseMe: When Small Models Compose a Visual Symphony

Field Notes from “An Adventure in Thousand Token Wood” — Build Small Hackathon 2026

音乐视频是极具个人色彩的艺术品。它们将你听到的歌曲转化为一种可见、可感的体验。然而,即使是制作一个简单的歌词视频——即歌词随音乐同步出现的视频——也是一个繁琐的手动过程。你需要在视频编辑器中为歌词设置关键帧,凭听觉将文字与节拍对齐,还要费力寻找“氛围感”相符的素材。一首 3 分钟的歌,往往需要数小时的工作。我们构建 aMuseMe 是为了提出一个不同的问题:如果只需上传一个音频文件,就能得到一个完整的、风格化的歌词视频,会怎样?无需歌词文本,无需时间轴编辑,无需寻找素材。只需输入音乐,输出视频。而且,我们仅用了总计 35 亿参数的模型就实现了这一点。

The Idea: Kinetic Typography Meets Small AI

创意:动态排版与小型 AI 的碰撞

动态排版(Kinetic Typography)——即文字随语音同步移动、缩放和动画化——是屏幕上呈现文字最引人入胜的方式之一。音乐歌词视频是一个完美的切入点:每个单词都有精确的时间戳,每一行歌词都有其情感基调,这可以决定它的视觉呈现方式。我们构想了一个流程:

  • AI 聆听歌曲并为每个单词打上时间戳
  • AI 阅读歌词并决定如何将其拆分为显示行
  • AI 为每个片段绘制匹配的背景图
  • 渲染器将这一切合成为流畅的 30fps 高清视频

难点在于:所有四个步骤都必须在黑客松 320 亿参数的预算限制内完成。没有云端 API,一切都在本地运行。

The Architecture: Four Small Models, One Pipeline

架构:四个小型模型,一条流水线

Stage 1: The Listener — Whisper large-v3 (~1.55B) 第一阶段:听者 — Whisper large-v3 (~15.5 亿参数)

我们使用 faster-whisper(一个经 CTranslate2 优化的移植版)从原始音频中提取单词级时间戳。不是句子级,而是单词级。当歌手在 4.72 秒处唱出“heart”时,我们知道它从 4.72 秒开始,到 5.01 秒结束。这种精度让最终的视频充满生命力。文字不仅仅是逐行出现,每个单词都会在唱出的那一毫秒精准点亮。

调优的深坑:从歌曲(而非清晰语音)中获取准确的单词时间戳需要大量的实验:condition_on_previous_text=True 能显著提高准确性——Whisper 使用其之前的输出作为上下文,从而“记住”歌曲的词汇。但这会导致在间奏期间出现无限幻觉循环(Whisper 会用重复的虚假歌词填补空白)。VAD(语音活动检测)解决了幻觉问题。我们使用了激进的阈值——min_silence_duration_ms=2000, speech_pad_ms=2000, min_speech_duration_ms=50——这样 Whisper 只会处理有人声的部分。我们最初为了速度使用了 whisper-base(7400 万参数),但对于快速演唱,单词边界的准确性很差。large-v3 是最佳平衡点:既能准确处理歌曲,又完全在 320 亿参数的预算之内。

Stage 2: The Director — MiniCPM5-1B + Outlines 第二阶段:导演 — MiniCPM5-1B + Outlines

这是流水线的创意大脑。原始的 Whisper 输出是一串带有时间戳的单词列表,但歌词视频需要分行。例如,“Every heartbeat echoes feel like grooving my veins”需要变成: Every heartbeat echoes ← 第一行 feel like grooving my veins ← 第二行

基于规则的方法(在静音处拆分,限制 7 个单词)虽然可行,但产生的断句机械且不自然。LLM 理解短语结构——它知道“breaking all of these chains”应该保持在一起。我们使用了 MiniCPM5-1B(由本次黑客松主要赞助商 OpenBMB 提供)——这是一个 10 亿参数的语言模型,足够小,可以与 Whisper 和 SD-Turbo 在单个 GPU 上同时运行。对于每约 10 个单词的片段,模型会:

  • 将单词拆分为显示行——决定每行包含多少单词
  • 选择帧动画——zoom_in(放大以强调)、flash(闪烁以配合重音)、fade_to_black(淡出以配合安静结尾)、pan_left/pan_right(平移以产生轻微动感)

结构化生成的突破:小型 LLM 面临的最大挑战是输出的可靠性。1B 模型经常产生格式错误的 JSON、缺失字段或幻觉键。我们通过 Outlines 彻底解决了这个问题——这是一个在解码时将 LLM 的 Token 生成限制为符合 Pydantic 模式的库。模型在字面上无法生成无效的 JSON。无需重试,无需正则提取,无需解析失败。

from outlines import from_transformers, Generator
class Frame(BaseModel):
    count: int # 该行有多少单词
    frame_animation: FrameAnim # zoom_in, flash, pan_left 等
class SongFrames(BaseModel):
    frames: List[Frame]

model = from_transformers(hf_model, tokenizer)
generator = Generator(model, SongFrames) # 模式强制执行!
result = generator(prompt, max_new_tokens=256) # 结果永远是有效的 SongFrames

Stage 3: The Illustrator — SD-Turbo (~865M) 第三阶段:插画师 — SD-Turbo (~8.65 亿参数)

对于每一对歌词行,我们使用 SD-Turbo(Stability AI 的蒸馏版 Stable Diffusion 模型)生成电影级的背景图像。SD-Turbo 的魔力在于:它能在单次推理步骤中生成高质量图像,且 guidance_scale=0.0。我们将歌词文本与用户的风格提示词合并:“neon-lit futuristic city at night, vibrant glowing colors, cyberpunk aesthetic, breaking all of these chains”。对于一首 3 分钟、包含约 15 个分镜图像的歌曲,整个背景生成步骤在 GPU 上仅需约 2 秒。背景随后会被调暗(55% 遮罩),以确保白色/霓虹色的歌词在任何生成的图像上都清晰可读。

Stage 4: The Renderer — Pillow + FFmpeg 第四阶段:渲染器 — Pillow + FFmpeg

最后阶段是一个使用 Pillow 构建的自定义逐帧渲染器:

  • 单词级高亮:当前行的单词以主题色显示;未唱到的单词则变暗。随着每个单词的时间戳到来,它会点亮。
  • 帧级动画:LLM 选择的动画(缩放、平移、闪烁、淡入淡出)应用于整个文本块,创造出电影般的动感。
  • 智能文本换行:长行会自动换行,而不是缩小到无法阅读的大小。
  • 交叉淡入淡出过渡:背景图像通过 1 秒的 Alpha 通道过渡平滑融合。帧数据以原始 RGB 格式流式传输。