YuE2 环境装好、权重就位、第一段旋律跑通

文章导读
代码拉下来、权重也下载完了,卡住的往往不是“装没装”,而是不知道先验证哪一步。合理的顺序是先固定运行时与推理框架版本,再固定权重和代码的路径,然后用一段最短的旋律跑通推理,最后才看生成效果。这样安排的原因是每一步只引入一个变量:跑失败时,日志里的报错能直接对应到版本、路径或显存中的某一类,不用反复重装依赖或挪动权重目录。
📋 目录
  1. A 确认运行时与推理框架版本满足依赖
  2. B 放置代码与权重并核对目录结构
  3. C 用最小配置跑一次推理拿到音频文件
  4. D 首次失败时按日志判断卡在哪一阶段
  5. E 把跑通的配置存成固定脚本
A A

代码拉下来、权重也下载完了,卡住的往往不是“装没装”,而是不知道先验证哪一步。合理的顺序是先固定运行时与推理框架版本,再固定权重和代码的路径,然后用一段最短的旋律跑通推理,最后才看生成效果。这样安排的原因是每一步只引入一个变量:跑失败时,日志里的报错能直接对应到版本、路径或显存中的某一类,不用反复重装依赖或挪动权重目录。

代码与权重到位后,判断链路是否通的最小依据是三件事:版本能对上、配置里的路径和磁盘实际位置一致、最小推理能落下一个音频文件。按依赖、路径、推理各验证一步,每步只变动一个变量;出错时再按日志区分导入失败、找不到权重还是显存不足,定位会快很多。这套顺序适合单机首次部署;多卡、量化或自定义权重的仓库,仍需以其说明和自身环境为准。

确认运行时与推理框架版本满足依赖

先激活准备用来跑推理的虚拟环境再查版本,否则查到的可能是系统 Python。通常需要确认三件事:Python 版本在依赖文件允许的范围内、torch 与本机驱动能对应上、推理脚本 import 的其它库都已装好。依赖文件常见三种:requirements.txt、pyproject.toml 里的 dependencies、environment.yml 里的 channels 与 dependencies。重点看 torch 这类带本地版本后缀的条目,它决定了 CUDA 版本,不能只看主版本号。

python -V
python -c "import sys, torch; print(sys.version.split()[0], torch.__version__, torch.version.cuda, torch.cuda.is_available())"
pip show torch
pip list | grep -i -e torch -e transformers -e soundfile
nvidia-smi

具体版本组合以实际仓库说明为准。如果仓库没有给出明确约束,先保持一个能成功 import 的组合,不要在同一次调试里同时升级驱动和框架,否则出问题时很难判断是哪一步引入的。

放置代码与权重并核对目录结构

代码和权重放在哪里并不重要,重要的是配置里写的路径和磁盘上的实际情况一致。先看目录里应该出现的文件类型:推理入口是 .py,配置是 .yaml 或 .json,权重通常是 .safetensors、.bin、.pt 或 .ckpt,另外还有 tokenizer 需要的 vocab、merges、config.json 一类小文件。分片权重会带 model-00001-of-0000N 这样的编号,缺任何一片都会在加载时报错。

YuE2/
├── code/            # 推理入口与配置
├── weights/         # 权重、tokenizer 资源
└── outputs/         # 音频输出,先建空目录

需要改的配置字段通常包括模型或权重目录(model_path、ckpt_dir、weight_dir 之类)、tokenizer 路径、输出目录 output_dir,以及 device 或 device_map。相对路径以启动进程时的工作目录为基准,容易和写配置的人想的不一样,建议直接写绝对路径。

model_path: /path/to/YuE2/weights
tokenizer_path: /path/to/YuE2/weights/tokenizer
output_dir: /path/to/YuE2/outputs
device: cuda:0

字段名以仓库实际配置为准。放好后用 ls -lh 确认权重文件不是 0 字节,再数一下分片数量是否与索引文件里记录的一致。

用最小配置跑一次推理拿到音频文件

先跑通链路,再谈效果。第一段旋律建议给最短的时长、最少的步数,避免把加载问题和显存问题混在一起。先看入口支持哪些参数,再按最小骨架执行。

YuE2 环境装好、权重就位、第一段旋律跑通
cd /path/to/YuE2/code
python infer.py `--help`
python infer.py \
  `--model-dir` /path/to/YuE2/weights \
  `--prompt` "一段八小节的简单旋律" \
  `--output-dir` /path/to/YuE2/outputs \
  `--device` cuda:0

参数名以入口的 `--help` 输出为准,不同仓库可能是 `--model-dir`、`--ckpt` 或 `--config`。日志里的成功标志通常是:模型与权重加载完成、设备信息打印为 cuda:0、生成步数在递增、最后出现写入或保存文件的那一行。输出一般落在 output_dir 下,扩展名是 .wav 或 .mp3。

ls -lh /path/to/YuE2/outputs
soxi /path/to/YuE2/outputs/*.wav

用 soxi 或 ffprobe 看采样率和时长,只要不是 0 秒,就说明从加载到写出文件的链路是通的,后面再调旋律质量和生成时长。

首次失败时按日志判断卡在哪一阶段

第一次跑失败时,先看 traceback 最后的异常类型,再决定查什么,不要直接重装环境。常见的三类可以这样区分。

  • 依赖缺失:日志里是 ModuleNotFoundError、ImportError、No module named,或 libcudart.so、undefined symbol 这类加载失败。检查动作:用 which python 确认解释器是不是目标虚拟环境,pip show 对应包看是否装在此环境中,torch 与驱动不匹配时换一个对应 CUDA 的版本。
  • 权重缺失或对不上:FileNotFoundError 指向某个 .safetensors 或 .bin,或 RuntimeError 里出现 Error(s) in loading state_dict、size mismatch、unexpected key。检查动作:把报错里的完整路径和磁盘上的实际路径逐段对照,确认相对路径的基准目录,确认分片齐全,确认这份权重与代码期望的版本一致。
  • 显存不足:torch.cuda.OutOfMemoryError 或 CUDA out of memory。检查动作:nvidia-smi 看是不是有别的进程占着卡,缩短生成长度、降低精度或改为单卡,先跑通一个很短的片段。

如果日志里没有这些关键字,进程却在加载阶段停住不动,可以把模型加载和生成拆成两步执行,看日志停在某一句输出之后,再回到对应小节检查版本或路径。

把跑通的配置存成固定脚本

跑通一次之后,把命令、路径和参数固化成脚本,下一次换旋律只改提示词。路径和提示词都留成占位符,方便换机器或换权重目录。

#!/usr/bin/env bash
set -euo pipefail

PYTHON_BIN="${PYTHON_BIN:-python}"
CODE_DIR="${CODE_DIR:-/path/to/YuE2/code}"
WEIGHT_DIR="${WEIGHT_DIR:-/path/to/YuE2/weights}"
OUT_DIR="${OUT_DIR:-/path/to/YuE2/outputs}"
PROMPT="${PROMPT:-一段八小节的简单旋律}"

mkdir -p "${OUT_DIR}"
cd "${CODE_DIR}"
"${PYTHON_BIN}" infer.py \
  `--model-dir` "${WEIGHT_DIR}" \
  `--prompt` "${PROMPT}" \
  `--output-dir` "${OUT_DIR}" \
  `--device` "${DEVICE:-cuda:0}" 2>&1 | tee "${OUT_DIR}/run.log"
ls -lh "${OUT_DIR}"

重跑时的验证点:脚本退出码为 0;OUT_DIR 下出现新的音频文件,用 ls -lh 确认大小不是 0;run.log 末尾能看到保存完成那一行;再用 soxi 看一次时长。如果换了权重目录或升级了依赖,先跑这个脚本,不要同时改生成参数,这样两次日志才容易对比出是哪一步发生了变化。