Natooz/MidiTok

MIDI / symbolic music tokenizers for Deep Learning models 🎶

MidiTok

摘要 MidiTok 是一个 Python 包,将 MIDI 和 abc 音乐文件转换为 token 序列。这些 token 可以输入机器学习模型(例如 Transformer)用于音乐生成、转录或其他 MIR 任务。

目的 提供统一接口以支持各种音乐 tokenization 方法,通过 BPE/Unigram/WordPiece 训练 tokenizer,提供数据增强工具,并与 Hugging Face Hub 整合以共享模型。

工作原理

  • 使用 Symusic 读取/写入 MIDI 和 abc 文件。
  • tokenizer(如 REMI)接受一个 Score 对象并输出 token ID 列表。
  • tokenizer 可以在 MIDI 文件语料库上训练(tokenizer.train)以通过 BPE、Unigram 或 WordPiece 学习词汇表。
  • 训练好的 tokenizer 可进行编码(tokenizer(midi))和解码(tokenizer(tokens)),返回 PyTorch、TensorFlow 或 NumPy 张量。
  • 辅助工具可将长 MIDI 文件分割为训练大小的块,构建 PyTorch DatasetMIDIDataCollator,并生成用于模型训练的 DataLoader

主要特性

  • 实现多种 tokenization:REMI、REMI+、MIDI‑Like、TSD、Structured、CPWord、Octuple、MuMIDI、MMM、PerTok。
  • 支持使用 BPE、Unigram、WordPiece 训练 tokenizer。
  • 包含数据增强方法。
  • Hugging Face Hub 集成(push_to_hubfrom_pretrained)。
  • 兼容 PyTorch、TensorFlow 与 NumPy 张量。
  • 提供 DatasetMIDIDataCollatorsplit_files_for_training 工具。

使用示例

from miditok import REMI, TokenizerConfig
from symusic import Score

config = TokenizerConfig(num_velocities=16, use_chords=True, use_programs=True)
tokenizer = REMI(config)

midi = Score("path/to/your_midi.mid
tokens = tokenizer(midi)               # → token IDs
converted_back = tokenizer(tokens)     # → Score object

训练 tokenizer:

from pathlib import Path
files = list(Path("midis\)).glob("**/*.mid
tokenizer.train(vocab_size=30000, files_paths=files)
tokenizer.save(Path("tokenizer.json
tokenizer.push_to_hub("username/model-name", private=True, token="HF_TOKEN

为 PyTorch 准备数据:

from miditok.utils import split_files_for_training
from miditok.pytorch_data import DatasetMIDI, DataCollator
from torch.utils.data import DataLoader

split_files_for_training(files_paths=files, tokenizer=tokenizer,
                         save_dir=Path("chunks\)), max_seq_len=1024)

dataset = DatasetMIDI(
    files_paths=list(Path("chunks\)).glob("**/*.mid\)),
    tokenizer=tokenizer,
    max_seq_len=1024,
    bos_token_id=tokenizer["BOS_None"],
    eos_token_id=tokenizer["EOS_None\)
)
collator = DataCollator(tokenizer.pad_token_id, copy_inputs_as_labels=True)
dataloader = DataLoader(dataset, batch_size=64, collate_fn=collator)

for batch in dataloader:
    # train your model on batch
    ...

限制 / TODO

  • 音乐 XML 支持尚未实现。
  • 缺少 no_duration_drums 选项以移除鼓的 duration token。
  • 未处理 Control Change 消息。
  • 全域/轨事件解析可通过 Rust/C++ 绑定加速。

相关

  • 项目
  • 项目
  • Dispatch
  • 项目
  • 项目