[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
This is the official repository of the IEEE SLT 2024 paper Self-Supervised Syllable Discovery Based on Speaker-Disentangled HuBERT.
Outperformed Z.ai GLM-4-Voice by 5% in semantic understanding while using 42× less training compute


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)
fastapi run app_server.py
python app_client.py
You can download pretrained models from Hugging Face.
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)
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
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
python main_unit2speech.py train_dit --config=configs/unit2speech/default.yaml
GROUP_NAME=
qsub -g ${GROUP_NAME} scripts/run_speechlm_deepspeed.bash configs/speechlm/default.yaml
@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},
}
185 commits
Python
95.4%
Shell
2.6%
Jupyter Notebook
2.0%
[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
This is the official repository of the IEEE SLT 2024 paper Self-Supervised Syllable Discovery Based on Speaker-Disentangled HuBERT.
Outperformed Z.ai GLM-4-Voice by 5% in semantic understanding while using 42× less training compute


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)
fastapi run app_server.py
python app_client.py
You can download pretrained models from Hugging Face.
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)
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
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
python main_unit2speech.py train_dit --config=configs/unit2speech/default.yaml
GROUP_NAME=
qsub -g ${GROUP_NAME} scripts/run_speechlm_deepspeed.bash configs/speechlm/default.yaml
@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},
}
185 commits
Python
95.4%
Shell
2.6%
Jupyter Notebook
2.0%