Views
No views yet
canopylabs/orpheus-3b-0.1-pretrainedpip install -U "huggingface_hub>=0.30.0,<1.0.0" hf-xet1mkdir -p pretrained_models/bengali-orpheus-tts-adapter
2
3hf download kawshikbuet17/bengali-orpheus-tts-adapter \
4 --repo-type model \
5 --local-dir pretrained_models/bengali-orpheus-tts-adapterls -lah pretrained_models/bengali-orpheus-tts-adapterhf auth login1import torch
2
3from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
4from peft import PeftModel
5
6
7base_model_id = "canopylabs/orpheus-3b-0.1-pretrained"
8adapter_model_id = "kawshikbuet17/bengali-orpheus-tts-adapter"
9
10compute_dtype = torch.bfloat16 if torch.cuda.is_available() and torch.cuda.is_bf16_supported() else torch.float16
11
12tokenizer = AutoTokenizer.from_pretrained(base_model_id)
13
14bnb_config = BitsAndBytesConfig(
15 load_in_4bit=True,
16 bnb_4bit_quant_type="nf4",
17 bnb_4bit_use_double_quant=True,
18 bnb_4bit_compute_dtype=compute_dtype,
19)
20
21base_model = AutoModelForCausalLM.from_pretrained(
22 base_model_id,
23 quantization_config=bnb_config,
24 device_map="auto",
25)
26
27model = PeftModel.from_pretrained(
28 base_model,
29 adapter_model_id,
30)
31
32model.eval()infer_bengali_orpheus_tts.py:1import sys
2import torch
3import soundfile as sf
4
5from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
6from peft import PeftModel
7from snac import SNAC
8
9
10BASE_MODEL = "canopylabs/orpheus-3b-0.1-pretrained"
11DEFAULT_ADAPTER = "kawshikbuet17/bengali-orpheus-tts-adapter"
12
13TOKENIZER_LENGTH = 128256
14
15END_OF_TEXT = 128009
16
17START_OF_SPEECH = TOKENIZER_LENGTH + 1
18END_OF_SPEECH = TOKENIZER_LENGTH + 2
19
20START_OF_HUMAN = TOKENIZER_LENGTH + 3
21END_OF_HUMAN = TOKENIZER_LENGTH + 4
22
23START_OF_AI = TOKENIZER_LENGTH + 5
24END_OF_AI = TOKENIZER_LENGTH + 6
25
26PAD_TOKEN = TOKENIZER_LENGTH + 7
27
28AUDIO_TOKEN_START = TOKENIZER_LENGTH + 10
29AUDIO_TOKEN_END = AUDIO_TOKEN_START + 7 * 4096
30
31SAMPLE_RATE = 24000
32
33
34def build_prompt_ids(tokenizer, text: str):
35 text_ids = tokenizer.encode(text, add_special_tokens=True)
36 text_ids.append(END_OF_TEXT)
37
38 return (
39 [START_OF_HUMAN]
40 + text_ids
41 + [END_OF_HUMAN]
42 + [START_OF_AI]
43 + [START_OF_SPEECH]
44 )
45
46
47def extract_audio_tokens(generated_ids):
48 audio_tokens = []
49
50 for token in generated_ids:
51 token = int(token)
52
53 if token in [END_OF_SPEECH, END_OF_AI, PAD_TOKEN]:
54 break
55
56 if AUDIO_TOKEN_START <= token < AUDIO_TOKEN_END:
57 audio_tokens.append(token)
58
59 usable_len = (len(audio_tokens) // 7) * 7
60 return audio_tokens[:usable_len]
61
62
63def audio_tokens_to_waveform(snac_model, audio_tokens, device):
64 if len(audio_tokens) == 0:
65 raise RuntimeError("No audio tokens generated.")
66
67 if len(audio_tokens) % 7 != 0:
68 raise RuntimeError(f"Audio token length must be divisible by 7, got {len(audio_tokens)}")
69
70 n_frames = len(audio_tokens) // 7
71
72 codes_0 = []
73 codes_1 = []
74 codes_2 = []
75
76 for i in range(n_frames):
77 t = audio_tokens[i * 7 : (i + 1) * 7]
78
79 c0 = t[0] - AUDIO_TOKEN_START
80
81 c1_0 = t[1] - AUDIO_TOKEN_START - 4096
82 c2_0 = t[2] - AUDIO_TOKEN_START - 2 * 4096
83 c2_1 = t[3] - AUDIO_TOKEN_START - 3 * 4096
84 c1_1 = t[4] - AUDIO_TOKEN_START - 4 * 4096
85 c2_2 = t[5] - AUDIO_TOKEN_START - 5 * 4096
86 c2_3 = t[6] - AUDIO_TOKEN_START - 6 * 4096
87
88 vals = [c0, c1_0, c2_0, c2_1, c1_1, c2_2, c2_3]
89 if any(v < 0 or v >= 4096 for v in vals):
90 continue
91
92 codes_0.append(c0)
93 codes_1.extend([c1_0, c1_1])
94 codes_2.extend([c2_0, c2_1, c2_2, c2_3])
95
96 if not codes_0:
97 raise RuntimeError("No valid SNAC frames found from generated tokens.")
98
99 codes = [
100 torch.tensor([codes_0], dtype=torch.long, device=device),
101 torch.tensor([codes_1], dtype=torch.long, device=device),
102 torch.tensor([codes_2], dtype=torch.long, device=device),
103 ]
104
105 with torch.inference_mode():
106 audio = snac_model.decode(codes)
107
108 return audio.detach().squeeze().float().cpu().numpy()
109
110
111def main():
112 adapter_path = sys.argv[1] if len(sys.argv) >= 2 else DEFAULT_ADAPTER
113
114 prompt = (
115 sys.argv[2]
116 if len(sys.argv) >= 3
117 else "আপনার অ্যাকাউন্টের লাস্ট রিচার্জ কত ছিল, বলতে পারবেন?"
118 )
119
120 out_path = sys.argv[3] if len(sys.argv) >= 4 else "bengali_orpheus_tts.wav"
121
122 device = "cuda" if torch.cuda.is_available() else "cpu"
123 compute_dtype = torch.bfloat16 if torch.cuda.is_available() and torch.cuda.is_bf16_supported() else torch.float16
124
125 print("Base model:", BASE_MODEL)
126 print("Adapter:", adapter_path)
127 print("Prompt:", prompt)
128 print("Output:", out_path)
129 print("Device:", device)
130 print("Compute dtype:", compute_dtype)
131
132 tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL)
133
134 bnb_config = BitsAndBytesConfig(
135 load_in_4bit=True,
136 bnb_4bit_quant_type="nf4",
137 bnb_4bit_use_double_quant=True,
138 bnb_4bit_compute_dtype=compute_dtype,
139 )
140
141 print("Loading base model in 4-bit...")
142 base_model = AutoModelForCausalLM.from_pretrained(
143 BASE_MODEL,
144 quantization_config=bnb_config,
145 device_map="auto",
146 )
147
148 print("Loading QLoRA adapter...")
149 model = PeftModel.from_pretrained(base_model, adapter_path)
150 model.eval()
151
152 print("Loading SNAC decoder...")
153 snac_model = SNAC.from_pretrained("hubertsiuzdak/snac_24khz").to(device)
154 snac_model.eval()
155
156 input_ids_list = build_prompt_ids(tokenizer, prompt)
157
158 input_ids = torch.tensor([input_ids_list], dtype=torch.long, device=device)
159 attention_mask = torch.ones_like(input_ids)
160
161 print("Generating speech tokens...")
162
163 with torch.inference_mode():
164 output = model.generate(
165 input_ids=input_ids,
166 attention_mask=attention_mask,
167 max_new_tokens=2048,
168 do_sample=True,
169 temperature=0.6,
170 top_p=0.95,
171 repetition_penalty=1.1,
172 eos_token_id=END_OF_SPEECH,
173 pad_token_id=PAD_TOKEN,
174 )
175
176 generated_new_tokens = output[0][input_ids.shape[1]:].tolist()
177 audio_tokens = extract_audio_tokens(generated_new_tokens)
178
179 print("Generated new tokens:", len(generated_new_tokens))
180 print("Audio tokens:", len(audio_tokens))
181 print("Audio frames:", len(audio_tokens) // 7)
182
183 audio = audio_tokens_to_waveform(snac_model, audio_tokens, device)
184
185 sf.write(out_path, audio, SAMPLE_RATE)
186
187 print("Saved:", out_path)
188
189
190if __name__ == "__main__":
191 main()1python infer_bengali_orpheus_tts.py \
2 kawshikbuet17/bengali-orpheus-tts-adapter \
3 "আপনার অ্যাকাউন্টের লাস্ট রিচার্জ কত ছিল, বলতে পারবেন?" \
4 output.wavpython infer_bengali_orpheus_tts.pykawshikbuet17/bengali-telecom-customer-care-speech1base_model: canopylabs/orpheus-3b-0.1-pretrained
2language: Bengali / Bangla
3task: Text-to-Speech
4adapter_type: QLoRA / LoRA
5lora_r: 16
6lora_alpha: 32
7lora_dropout: 0.05canopylabs/orpheus-3b-0.1-pretrained for inference.