YarnGPT-local is a text-to-speech (TTS) model designed to synthesize Yoruba, Igbo and Hausa leveraging pure language modelling without external adapters or complex architectures, offering high-quality, natural, and culturally relevant speech synthesis for diverse applications.
The model can generate audio on its own but its better to use a voice to prompt the model, there are about 10 voices supported by default:
1# clone the YarnGPT repo to get access to the `audiotokenizer`
2!git clone https://github.com/saheedniyi02/yarngpt.git
3
4
5# install some necessary libraries
6!pip install outetts==0.2.3 uroman
7
8#import some important packages
9import os
10import re
11import json
12import torch
13import inflect
14import random
15import uroman as ur
16import numpy as np
17import torchaudio
18import IPython
19from transformers import AutoModelForCausalLM, AutoTokenizer
20from outetts.wav_tokenizer.decoder import WavTokenizer
21from yarngpt.audiotokenizer import AudioTokenizerForLocal
22
23
24# download the wavtokenizer weights and config (to encode and decode the audio)
25!wget https://huggingface.co/novateur/WavTokenizer-medium-speech-75token/resolve/main/wavtokenizer_mediumdata_frame75_3s_nq1_code4096_dim512_kmeans200_attn.yaml
26!wget https://huggingface.co/novateur/WavTokenizer-large-speech-75token/resolve/main/wavtokenizer_large_speech_320_24k.ckpt
27
28# model path and wavtokenizer weight path (the paths are assumed based on Google colab, a different environment might save the weights to a different location).
29hf_path="saheedniyi/YarnGPT-local"
30wav_tokenizer_config_path="/content/wavtokenizer_mediumdata_frame75_3s_nq1_code4096_dim512_kmeans200_attn.yaml"
31wav_tokenizer_model_path = "/content/wavtokenizer_large_speech_320_24k.ckpt"
32
33# create the AudioTokenizer object
34audio_tokenizer=AudioTokenizerForLocal(
35 hf_path,wav_tokenizer_model_path,wav_tokenizer_config_path
36)
37
38#load the model weights
39
40model = AutoModelForCausalLM.from_pretrained(hf_path,torch_dtype="auto").to(audio_tokenizer.device)
41
42# your input text
43text="Ẹ maa rii pe lati bi ọsẹ meloo kan ni ijiroro ti wa lati ọdọ awọn ileeṣẹ wọnyi wi pe wọn fẹẹ ṣafikun si owo ipe pẹlu ida ọgọrun-un."
44
45# creating a prompt, when creating a prompt, there is an optional `speaker_name` parameter
46prompt=audio_tokenizer.create_prompt(text,"yoruba","yoruba_male2")
47
48# tokenize the prompt
49input_ids=audio_tokenizer.tokenize_prompt(prompt)
50
51# generate output from the model, you can tune the `.generate` parameters as you wish
52output = model.generate(
53 input_ids=input_ids,
54 temperature=0.1,
55 repetition_penalty=1.1,
56 num_beams=4,
57 max_length=4000,
58 )
59
60# convert the output to "audio codes"
61codes=audio_tokenizer.get_codes(output)
62
63# converts the codes to audio
64audio=audio_tokenizer.get_audio(codes)
65
66# play the audio
67IPython.display.Audio(audio,rate=24000)
68
69# save the audio
70torchaudio.save(f"audio.wav", audio, sample_rate=24000)
1# clone the YarnGPT repo to get access to the `audiotokenizer`
2!git clone https://github.com/saheedniyi02/yarngpt.git
3
4
5# install some necessary libraries
6!pip install outetts uroman trafilatura pydub
7
8
9#import important packages
10import os
11import re
12import json
13import torch
14import inflect
15import random
16import requests
17import trafilatura
18import inflect
19import uroman as ur
20import numpy as np
21import torchaudio
22import IPython
23from pydub import AudioSegment
24from pydub.effects import normalize
25from transformers import AutoModelForCausalLM, AutoTokenizer
26from outetts.wav_tokenizer.decoder import WavTokenizer
27from yarngpt.audiotokenizer import AudioTokenizer,AudioTokenizerForLocal
28
29# download the `WavTokenizer` files
30!wget https://huggingface.co/novateur/WavTokenizer-medium-speech-75token/resolve/main/wavtokenizer_mediumdata_frame75_3s_nq1_code4096_dim512_kmeans200_attn.yaml
31!wget https://huggingface.co/novateur/WavTokenizer-large-speech-75token/resolve/main/wavtokenizer_large_speech_320_24k.ckpt
32
33tokenizer_path="saheedniyi/YarnGPT-local"
34wav_tokenizer_config_path="/content/wavtokenizer_mediumdata_frame75_3s_nq1_code4096_dim512_kmeans200_attn.yaml"
35wav_tokenizer_model_path = "/content/wavtokenizer_large_speech_320_24k.ckpt"
36
37
38audio_tokenizer=AudioTokenizerForLocal(
39 tokenizer_path,wav_tokenizer_model_path,wav_tokenizer_config_path
40 )
41
42model = AutoModelForCausalLM.from_pretrained(tokenizer_path,torch_dtype="auto").to(audio_tokenizer.device)
43
44# Split text into chunks
45def split_text_into_chunks(text, word_limit=25):
46 sentences=[sentence.strip() for sentence in text.split('.') if sentence.strip()]
47 chunks=[]
48 for sentence in sentences:
49 chunks.append(".")
50 sentence_splitted=sentence.split(" ")
51 num_words=len(sentence_splitted)
52 start_index=0
53 if num_words>word_limit:
54 while start_index<num_words:
55 end_index=min(num_words,start_index+word_limit)
56 chunks.append(" ".join(sentence_splitted[start_index:start_index+word_limit]))
57 start_index=end_index
58 else:
59 chunks.append(sentence)
60 return chunks
61
62# reduce the speed of the audio, results from the local languages are always fast
63def speed_change(sound, speed=0.9):
64 # Manually override the frame_rate. This tells the computer how many
65 # samples to play per second
66 sound_with_altered_frame_rate = sound._spawn(sound.raw_data, overrides={
67 "frame_rate": int(sound.frame_rate * speed)
68 })
69 # convert the sound with altered frame rate to a standard frame rate
70 # so that regular playback programs will work right. They often only
71 # know how to play audio at standard frame rate (like 44.1k)
72 return sound_with_altered_frame_rate.set_frame_rate(sound.frame_rate)
73
74
75page=requests.get("https://alaroye.org/a-maa-too-fo-ipinle-ogun-mo-omo-egbe-okunkun-meje-lowo-ti-te-bayii-omolola/")
76content=trafilatura.extract(page.text)
77chunks=split_text_into_chunks(content)
78
79
80all_codes=[]
81for i,chunk in enumerate(chunks):
82 print(i)
83 print("\n")
84 print(chunk)
85 if chunk==".":
86 #add silence for 0.5 seconds if we encounter a full stop
87 all_codes.extend([453]*38)
88 else:
89 prompt=audio_tokenizer.create_prompt(chunk,lang="yoruba",speaker_name="yoruba_female2")
90 input_ids=audio_tokenizer.tokenize_prompt(prompt)
91 output = model.generate(
92 input_ids=input_ids,
93 temperature=0.1,
94 repetition_penalty=1.1,
95 max_length=4000,
96 num_beams=5,
97 )
98 codes=audio_tokenizer.get_codes(output)
99 all_codes.extend(codes)
100
101
102audio=audio_tokenizer.get_audio(all_codes)
103
104#display the output
105IPython.display.Audio(audio,rate=24000)
106
107#save audio
108torchaudio.save(f"news1.wav", audio, sample_rate=24000)
109
110#convert file to an `AudioSegment` object for furher processing
111audio_dub=AudioSegment.from_file("news1.wav")
112
113# reduce audio speed: it reduces quality also
114speed_change(audio_dub,0.9)
Generate yoruba, igbo and hausa speech for experimental purposes.
The model is not suitable for generating speech in languages other than Yoruba, Igbo and Hausa.
Users (both direct and downstream) should be made aware of the risks, biases, and limitations of the model. Feedback and diverse training data contributions are encouraged.
Trained on open source dataset on Yoruba, Igbo and Hausa.
Audio files were preprocessed and resampled to 24Khz and tokenized using
wavtokenizer.
1@misc{yarngpt2025,
2 author = {Saheed Azeez},
3 title = {YarnGPT: Nigerian-Accented English Text-to-Speech Model},
4 year = {2025},
5 publisher = {Hugging Face},
6 url = {https://huggingface.co/SaheedAzeez/yarngpt}
7}