ryota-komatsu/speaker_disentangled_hubert

[IEEE OJSP'26, IEEE SLT'24] "Speaker-Disentangled Chunk-Wise Regression for Syllabic Tokenization"

46

stars

185

commits

Python

primary language

Sep 4, 2026

updated

arxiv.org/abs/2607.04064
self-supervised-learning
speech
speech-language-model
speech-processing
spoken-language-processing

README

SylReg: Speaker-Disentangled Chunk-Wise Regression for Syllabic Tokenization

License: MIT Python arXiv space model demo

This is the official repository of the IEEE SLT 2024 paper Self-Supervised Syllable Discovery Based on Speaker-Disentangled HuBERT.

News

  • 2026/07/04: Our paper has been accepted for publication in IEEE Open Journal of Signal Processing!
  • 2026/07/04: We release SylReg-LM 7B, an efficiently scalable interleaved syllable-text language model!

Results

Outperformed Z.ai GLM-4-Voice by 5% in semantic understanding while using 42× less training compute

Usage: Syllabic tokenization for speech language models

import re

import torch
import torchaudio
from datasets import load_dataset
from transformers import AutoModelForCausalLM, AutoTokenizer

from src.flow_matching import FlowMatchingWithBigVGan
from src.s5hubert import SylRegForSyllableDiscovery

# download pretrained models from hugging face hub
encoder = SylRegForSyllableDiscovery.from_pretrained("ryota-komatsu/SylReg-Distill", device_map="cuda", dtype="auto")
decoder = FlowMatchingWithBigVGan.from_pretrained("ryota-komatsu/SylReg-Decoder", device_map="cuda", dtype="auto")
speechlm = AutoModelForCausalLM.from_pretrained("ryota-komatsu/SylReg-LM-7B-Instruct", device_map="cuda", dtype="auto")
tokenizer = AutoTokenizer.from_pretrained("ryota-komatsu/SylReg-LM-7B-Instruct")

# load a waveform
dataset = load_dataset("fixie-ai/llama-questions", split="test")
dataset = dataset.with_format("torch")
input_values, sr = dataset[0]["audio"]["array"].unsqueeze(0), dataset[0]["audio"]["sampling_rate"]  # (1, T), int
input_values = torchaudio.functional.resample(input_values, sr, 16000)

# encode a waveform into syllabic units
outputs = encoder(input_values.to(encoder.device))
units = outputs[0]["units"]  # [3950, 67, ..., 503]
input_len = len(units)

# speech language modeling
messages = [
    {"role": "user", "content": "".join(f"<{unit}>" for unit in units)},
]

input_ids = tokenizer.apply_chat_template(
    messages,
    tokenize=True,
    add_generation_prompt=True,
    return_tensors="pt",
).input_ids.to(speechlm.device)

generated_ids = speechlm.generate(input_ids=input_ids, do_sample=True, temperature=0.8)[0]

units = tokenizer.decode(generated_ids)
units = torch.tensor([int(unit) for unit in re.findall(r"<(\d+)>", units)], device=decoder.device)
units = units[input_len:]

# unit-to-speech synthesis
generated_speech = decoder(units.unsqueeze(0)).waveform.cpu()  # (1, T)

torchaudio.save("input.wav", input_values, 16000)
torchaudio.save("output.wav", generated_speech, 16000)

Demo

fastapi run app_server.py
python app_client.py

Models

You can download pretrained models from Hugging Face.

Setup

We recommend Miniforge for virtual environments, as faiss-gpu is available only through conda, and Miniforge is free for commercial use.

sudo apt install git-lfs  # for UTMOS

conda create -y -n py310 -c pytorch -c conda-forge python=3.10 pip=24.0 setuptools=81.0.0 faiss-gpu=1.13.2 uv sox cuda-toolkit
conda activate py310
export UV_PROJECT_ENVIRONMENT=$CONDA_PREFIX
uv pip install -r requirements/requirements.txt

sh scripts/setup.sh

[!NOTE]

  • fairseq does not support python 3.11+
  • omegaconf 2.0.6 has a non-standard dependency specifier PyYAML>=5.1.*. pip 24.1 will enforce this behaviour change.
  • pin to setuptools=81.0.0 See https://github.com/tensorflow/tensorboard/issues/7003
  • install cuda-toolkit for MissingCUDAException: CUDA_HOME does not exist, unable to compile CUDA op(s)

Data Preparation

You can download datasets under dataset_root.

dataset_root=data  # be consistent with dataset.root in a config file

sh scripts/download_librispeech.sh ${dataset_root}
sh scripts/download_libritts.sh ${dataset_root}
sh scripts/download_librilight.sh ${dataset_root}  # 7TB
sh scripts/download_slm21.sh  # download sWUGGY and sBLIMP
sh scripts/download_tSC.sh

[!TIP] If you already have LibriSpeech, you can use it by editing a config file;

dataset:
  root: "/path/to/LibriSpeech/root" # ${dataset.root}/LibriSpeech/train-clean-100, train-clean-360, ...

Check the directory structure

dataset.root in a config file
└── LibriSpeech/
    ├── train-clean-100/
    ├── train-clean-360/
    ├── train-other-500/
    ├── dev-clean/
    ├── dev-other/
    ├── test-clean/
    ├── test-other/
    └── SPEAKERS.TXT

Syllabic tokenization

accelerate launch \
  --config_file=configs/speech2unit/ddp.yaml \
  --main_process_ip= \
  --machine_rank= \
  main_speech2unit.py train

To run only a sub-task (train, syllable_segmentation, quantize, or evaluate), specify it as an argument.

python main_speech2unit.py train --config configs/speech2unit/default.yaml

Unit-to-speech synthesis

python main_unit2speech.py train_dit --config=configs/unit2speech/default.yaml

Speech language modeling

GROUP_NAME=

qsub -g ${GROUP_NAME} scripts/run_speechlm_deepspeed.bash configs/speechlm/default.yaml

Citation

@article{Komatsu_SylReg_2026,
  author    = {Komatsu, Ryota and Kawakita, Kota and Okamoto, Takuma and Shinozaki, Takahiro},
  title     = {Speaker-Disentangled Chunk-Wise Regression for Syllabic Tokenization},
  year      = {2026},
  volume    = {7},
  journal   = {IEEE Open Journal of Signal Processing},
  pages     = {800--808},
}
@inproceedings{Komatsu_Self-Supervised_Syllable_Discovery_2024,
  author    = {Komatsu, Ryota and Shinozaki, Takahiro},
  title     = {Self-Supervised Syllable Discovery Based on Speaker-Disentangled {HuBERT}},
  year      = {2024},
  month     = {Dec.},
  booktitle = {IEEE Spoken Language Technology Workshop},
  pages     = {1131--1136},
  doi       = {10.1109/SLT61566.2024.10832325},
}

Contributors

ryota-komatsu

185 commits

ryota-komatsu/speaker_disentangled_hubert

[IEEE OJSP'26, IEEE SLT'24] "Speaker-Disentangled Chunk-Wise Regression for Syllabic Tokenization"

46

stars

185

commits

Python

primary language

Sep 4, 2026

updated

arxiv.org/abs/2607.04064
self-supervised-learning
speech
speech-language-model
speech-processing
spoken-language-processing

README

SylReg: Speaker-Disentangled Chunk-Wise Regression for Syllabic Tokenization

License: MIT Python arXiv space model demo

This is the official repository of the IEEE SLT 2024 paper Self-Supervised Syllable Discovery Based on Speaker-Disentangled HuBERT.

News

  • 2026/07/04: Our paper has been accepted for publication in IEEE Open Journal of Signal Processing!
  • 2026/07/04: We release SylReg-LM 7B, an efficiently scalable interleaved syllable-text language model!

Results

Outperformed Z.ai GLM-4-Voice by 5% in semantic understanding while using 42× less training compute

Usage: Syllabic tokenization for speech language models

import re

import torch
import torchaudio
from datasets import load_dataset
from transformers import AutoModelForCausalLM, AutoTokenizer

from src.flow_matching import FlowMatchingWithBigVGan
from src.s5hubert import SylRegForSyllableDiscovery

# download pretrained models from hugging face hub
encoder = SylRegForSyllableDiscovery.from_pretrained("ryota-komatsu/SylReg-Distill", device_map="cuda", dtype="auto")
decoder = FlowMatchingWithBigVGan.from_pretrained("ryota-komatsu/SylReg-Decoder", device_map="cuda", dtype="auto")
speechlm = AutoModelForCausalLM.from_pretrained("ryota-komatsu/SylReg-LM-7B-Instruct", device_map="cuda", dtype="auto")
tokenizer = AutoTokenizer.from_pretrained("ryota-komatsu/SylReg-LM-7B-Instruct")

# load a waveform
dataset = load_dataset("fixie-ai/llama-questions", split="test")
dataset = dataset.with_format("torch")
input_values, sr = dataset[0]["audio"]["array"].unsqueeze(0), dataset[0]["audio"]["sampling_rate"]  # (1, T), int
input_values = torchaudio.functional.resample(input_values, sr, 16000)

# encode a waveform into syllabic units
outputs = encoder(input_values.to(encoder.device))
units = outputs[0]["units"]  # [3950, 67, ..., 503]
input_len = len(units)

# speech language modeling
messages = [
    {"role": "user", "content": "".join(f"<{unit}>" for unit in units)},
]

input_ids = tokenizer.apply_chat_template(
    messages,
    tokenize=True,
    add_generation_prompt=True,
    return_tensors="pt",
).input_ids.to(speechlm.device)

generated_ids = speechlm.generate(input_ids=input_ids, do_sample=True, temperature=0.8)[0]

units = tokenizer.decode(generated_ids)
units = torch.tensor([int(unit) for unit in re.findall(r"<(\d+)>", units)], device=decoder.device)
units = units[input_len:]

# unit-to-speech synthesis
generated_speech = decoder(units.unsqueeze(0)).waveform.cpu()  # (1, T)

torchaudio.save("input.wav", input_values, 16000)
torchaudio.save("output.wav", generated_speech, 16000)

Demo

fastapi run app_server.py
python app_client.py

Models

You can download pretrained models from Hugging Face.

Setup

We recommend Miniforge for virtual environments, as faiss-gpu is available only through conda, and Miniforge is free for commercial use.

sudo apt install git-lfs  # for UTMOS

conda create -y -n py310 -c pytorch -c conda-forge python=3.10 pip=24.0 setuptools=81.0.0 faiss-gpu=1.13.2 uv sox cuda-toolkit
conda activate py310
export UV_PROJECT_ENVIRONMENT=$CONDA_PREFIX
uv pip install -r requirements/requirements.txt

sh scripts/setup.sh

[!NOTE]

  • fairseq does not support python 3.11+
  • omegaconf 2.0.6 has a non-standard dependency specifier PyYAML>=5.1.*. pip 24.1 will enforce this behaviour change.
  • pin to setuptools=81.0.0 See https://github.com/tensorflow/tensorboard/issues/7003
  • install cuda-toolkit for MissingCUDAException: CUDA_HOME does not exist, unable to compile CUDA op(s)

Data Preparation

You can download datasets under dataset_root.

dataset_root=data  # be consistent with dataset.root in a config file

sh scripts/download_librispeech.sh ${dataset_root}
sh scripts/download_libritts.sh ${dataset_root}
sh scripts/download_librilight.sh ${dataset_root}  # 7TB
sh scripts/download_slm21.sh  # download sWUGGY and sBLIMP
sh scripts/download_tSC.sh

[!TIP] If you already have LibriSpeech, you can use it by editing a config file;

dataset:
  root: "/path/to/LibriSpeech/root" # ${dataset.root}/LibriSpeech/train-clean-100, train-clean-360, ...

Check the directory structure

dataset.root in a config file
└── LibriSpeech/
    ├── train-clean-100/
    ├── train-clean-360/
    ├── train-other-500/
    ├── dev-clean/
    ├── dev-other/
    ├── test-clean/
    ├── test-other/
    └── SPEAKERS.TXT

Syllabic tokenization

accelerate launch \
  --config_file=configs/speech2unit/ddp.yaml \
  --main_process_ip= \
  --machine_rank= \
  main_speech2unit.py train

To run only a sub-task (train, syllable_segmentation, quantize, or evaluate), specify it as an argument.

python main_speech2unit.py train --config configs/speech2unit/default.yaml

Unit-to-speech synthesis

python main_unit2speech.py train_dit --config=configs/unit2speech/default.yaml

Speech language modeling

GROUP_NAME=

qsub -g ${GROUP_NAME} scripts/run_speechlm_deepspeed.bash configs/speechlm/default.yaml

Citation

@article{Komatsu_SylReg_2026,
  author    = {Komatsu, Ryota and Kawakita, Kota and Okamoto, Takuma and Shinozaki, Takahiro},
  title     = {Speaker-Disentangled Chunk-Wise Regression for Syllabic Tokenization},
  year      = {2026},
  volume    = {7},
  journal   = {IEEE Open Journal of Signal Processing},
  pages     = {800--808},
}
@inproceedings{Komatsu_Self-Supervised_Syllable_Discovery_2024,
  author    = {Komatsu, Ryota and Shinozaki, Takahiro},
  title     = {Self-Supervised Syllable Discovery Based on Speaker-Disentangled {HuBERT}},
  year      = {2024},
  month     = {Dec.},
  booktitle = {IEEE Spoken Language Technology Workshop},
  pages     = {1131--1136},
  doi       = {10.1109/SLT61566.2024.10832325},
}

Contributors

ryota-komatsu

185 commits

Languages

Python

95.4%

Shell

2.6%

Jupyter Notebook

2.0%