michael-chan-000 commited on
Commit
aedb5d2
·
verified ·
1 Parent(s): 3c13b21

Upload model

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ tokenizer.json filter=lfs diff=lfs merge=lfs -text
__pycache__/miner.cpython-312.pyc ADDED
Binary file (11.1 kB). View file
 
added_tokens.json ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "</think>": 151668,
3
+ "</tool_call>": 151658,
4
+ "</tool_response>": 151666,
5
+ "<think>": 151667,
6
+ "<tool_call>": 151657,
7
+ "<tool_response>": 151665,
8
+ "<tts_pad>": 151671,
9
+ "<tts_text_bos>": 151672,
10
+ "<tts_text_bos_single>": 151674,
11
+ "<tts_text_eod>": 151673,
12
+ "<|audio_end|>": 151670,
13
+ "<|audio_pad|>": 151675,
14
+ "<|audio_start|>": 151669,
15
+ "<|box_end|>": 151649,
16
+ "<|box_start|>": 151648,
17
+ "<|endoftext|>": 151643,
18
+ "<|file_sep|>": 151664,
19
+ "<|fim_middle|>": 151660,
20
+ "<|fim_pad|>": 151662,
21
+ "<|fim_prefix|>": 151659,
22
+ "<|fim_suffix|>": 151661,
23
+ "<|im_end|>": 151645,
24
+ "<|im_start|>": 151644,
25
+ "<|image_pad|>": 151655,
26
+ "<|object_ref_end|>": 151647,
27
+ "<|object_ref_start|>": 151646,
28
+ "<|quad_end|>": 151651,
29
+ "<|quad_start|>": 151650,
30
+ "<|repo_name|>": 151663,
31
+ "<|video_pad|>": 151656,
32
+ "<|vision_end|>": 151653,
33
+ "<|vision_pad|>": 151654,
34
+ "<|vision_start|>": 151652
35
+ }
chute_config.yml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Image + node + Chute for Vocence deploy. Required in the HF repo at build time.
2
+
3
+ Image:
4
+ from_base: parachutes/python:3.12
5
+ run_command:
6
+ - pip install torch torchaudio transformers accelerate huggingface_hub pyyaml soundfile librosa
7
+ - pip install -U qwen-tts
8
+ set_workdir: /app
9
+
10
+ NodeSelector:
11
+ gpu_count: 1
12
+ min_vram_gb_per_gpu: 24
13
+ include: ["pro_6000"]
14
+ exclude: []
15
+
16
+ Chute:
17
+ tagline: Vocence TTS — Qwen3 PromptTTS (weights in repo)
18
+ readme: Qwen3 12Hz TTS snapshot + miner.py for Vocence
19
+ shutdown_after_seconds: 86400
20
+ concurrency: 1
21
+ max_instances: 1
22
+ scaling_threshold: 0.5
23
+ tee: true
config.json ADDED
@@ -0,0 +1,304 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_name_or_path": "/home/base-model",
3
+ "add_cross_attention": false,
4
+ "architectures": [
5
+ "Qwen3TTSForConditionalGeneration"
6
+ ],
7
+ "assistant_token_id": 77091,
8
+ "bad_words_ids": null,
9
+ "begin_suppress_tokens": null,
10
+ "bos_token_id": null,
11
+ "chunk_size_feed_forward": 0,
12
+ "cross_attention_hidden_size": null,
13
+ "decoder_start_token_id": null,
14
+ "diversity_penalty": 0.0,
15
+ "do_sample": false,
16
+ "early_stopping": false,
17
+ "encoder_no_repeat_ngram_size": 0,
18
+ "eos_token_id": null,
19
+ "exponential_decay_length_penalty": null,
20
+ "finetuning_task": null,
21
+ "forced_bos_token_id": null,
22
+ "forced_eos_token_id": null,
23
+ "id2label": {
24
+ "0": "LABEL_0",
25
+ "1": "LABEL_1"
26
+ },
27
+ "im_end_token_id": 151645,
28
+ "im_start_token_id": 151644,
29
+ "is_decoder": false,
30
+ "is_encoder_decoder": false,
31
+ "label2id": {
32
+ "LABEL_0": 0,
33
+ "LABEL_1": 1
34
+ },
35
+ "length_penalty": 1.0,
36
+ "max_length": 20,
37
+ "min_length": 0,
38
+ "model_type": "qwen3_tts",
39
+ "no_repeat_ngram_size": 0,
40
+ "num_beam_groups": 1,
41
+ "num_beams": 1,
42
+ "num_return_sequences": 1,
43
+ "output_attentions": false,
44
+ "output_hidden_states": false,
45
+ "output_scores": false,
46
+ "pad_token_id": null,
47
+ "prefix": null,
48
+ "problem_type": null,
49
+ "pruned_heads": {},
50
+ "remove_invalid_values": false,
51
+ "repetition_penalty": 1.0,
52
+ "return_dict": true,
53
+ "return_dict_in_generate": false,
54
+ "sep_token_id": null,
55
+ "speaker_encoder_config": {
56
+ "enc_attention_channels": 128,
57
+ "enc_channels": [
58
+ 512,
59
+ 512,
60
+ 512,
61
+ 512,
62
+ 1536
63
+ ],
64
+ "enc_dilations": [
65
+ 1,
66
+ 2,
67
+ 3,
68
+ 4,
69
+ 1
70
+ ],
71
+ "enc_dim": 1024,
72
+ "enc_kernel_sizes": [
73
+ 5,
74
+ 3,
75
+ 3,
76
+ 3,
77
+ 1
78
+ ],
79
+ "enc_res2net_scale": 8,
80
+ "enc_se_channels": 128,
81
+ "mel_dim": 128,
82
+ "sample_rate": 24000
83
+ },
84
+ "suppress_tokens": null,
85
+ "talker_config": {
86
+ "_name_or_path": "",
87
+ "add_cross_attention": false,
88
+ "architectures": null,
89
+ "attention_bias": false,
90
+ "attention_dropout": 0,
91
+ "bad_words_ids": null,
92
+ "begin_suppress_tokens": null,
93
+ "bos_token_id": null,
94
+ "chunk_size_feed_forward": 0,
95
+ "code_predictor_config": {
96
+ "_name_or_path": "",
97
+ "add_cross_attention": false,
98
+ "architectures": null,
99
+ "attention_bias": false,
100
+ "attention_dropout": 0,
101
+ "bad_words_ids": null,
102
+ "begin_suppress_tokens": null,
103
+ "bos_token_id": null,
104
+ "chunk_size_feed_forward": 0,
105
+ "cross_attention_hidden_size": null,
106
+ "decoder_start_token_id": null,
107
+ "diversity_penalty": 0.0,
108
+ "do_sample": false,
109
+ "early_stopping": false,
110
+ "encoder_no_repeat_ngram_size": 0,
111
+ "eos_token_id": null,
112
+ "exponential_decay_length_penalty": null,
113
+ "finetuning_task": null,
114
+ "forced_bos_token_id": null,
115
+ "forced_eos_token_id": null,
116
+ "head_dim": 128,
117
+ "hidden_act": "silu",
118
+ "hidden_size": 1024,
119
+ "id2label": {
120
+ "0": "LABEL_0",
121
+ "1": "LABEL_1"
122
+ },
123
+ "initializer_range": 0.02,
124
+ "intermediate_size": 3072,
125
+ "is_decoder": false,
126
+ "is_encoder_decoder": false,
127
+ "label2id": {
128
+ "LABEL_0": 0,
129
+ "LABEL_1": 1
130
+ },
131
+ "layer_types": [
132
+ "full_attention",
133
+ "full_attention",
134
+ "full_attention",
135
+ "full_attention",
136
+ "full_attention"
137
+ ],
138
+ "length_penalty": 1.0,
139
+ "max_length": 20,
140
+ "max_position_embeddings": 65536,
141
+ "max_window_layers": 28,
142
+ "min_length": 0,
143
+ "no_repeat_ngram_size": 0,
144
+ "num_attention_heads": 16,
145
+ "num_beam_groups": 1,
146
+ "num_beams": 1,
147
+ "num_code_groups": 16,
148
+ "num_hidden_layers": 5,
149
+ "num_key_value_heads": 8,
150
+ "num_return_sequences": 1,
151
+ "output_attentions": false,
152
+ "output_hidden_states": false,
153
+ "output_scores": false,
154
+ "pad_token_id": 2148,
155
+ "prefix": null,
156
+ "problem_type": null,
157
+ "pruned_heads": {},
158
+ "remove_invalid_values": false,
159
+ "repetition_penalty": 1.0,
160
+ "return_dict": true,
161
+ "return_dict_in_generate": false,
162
+ "rms_norm_eps": 1e-06,
163
+ "rope_scaling": null,
164
+ "rope_theta": 1000000,
165
+ "sep_token_id": null,
166
+ "sliding_window": null,
167
+ "suppress_tokens": null,
168
+ "task_specific_params": null,
169
+ "temperature": 1.0,
170
+ "tf_legacy_loss": false,
171
+ "tie_encoder_decoder": false,
172
+ "tie_word_embeddings": false,
173
+ "tokenizer_class": null,
174
+ "top_k": 50,
175
+ "top_p": 1.0,
176
+ "torchscript": false,
177
+ "typical_p": 1.0,
178
+ "use_bfloat16": false,
179
+ "use_cache": true,
180
+ "use_sliding_window": false,
181
+ "vocab_size": 2048
182
+ },
183
+ "codec_bos_id": 2149,
184
+ "codec_eos_token_id": 2150,
185
+ "codec_language_id": {
186
+ "chinese": 2055,
187
+ "english": 2050,
188
+ "french": 2061,
189
+ "german": 2053,
190
+ "italian": 2070,
191
+ "japanese": 2058,
192
+ "korean": 2064,
193
+ "portuguese": 2071,
194
+ "russian": 2069,
195
+ "spanish": 2054
196
+ },
197
+ "codec_nothink_id": 2155,
198
+ "codec_pad_id": 2148,
199
+ "codec_think_bos_id": 2156,
200
+ "codec_think_eos_id": 2157,
201
+ "codec_think_id": 2154,
202
+ "cross_attention_hidden_size": null,
203
+ "decoder_start_token_id": null,
204
+ "diversity_penalty": 0.0,
205
+ "do_sample": false,
206
+ "early_stopping": false,
207
+ "encoder_no_repeat_ngram_size": 0,
208
+ "eos_token_id": null,
209
+ "exponential_decay_length_penalty": null,
210
+ "finetuning_task": null,
211
+ "forced_bos_token_id": null,
212
+ "forced_eos_token_id": null,
213
+ "head_dim": 128,
214
+ "hidden_act": "silu",
215
+ "hidden_size": 2048,
216
+ "id2label": {
217
+ "0": "LABEL_0",
218
+ "1": "LABEL_1"
219
+ },
220
+ "initializer_range": 0.02,
221
+ "intermediate_size": 6144,
222
+ "is_decoder": false,
223
+ "is_encoder_decoder": false,
224
+ "label2id": {
225
+ "LABEL_0": 0,
226
+ "LABEL_1": 1
227
+ },
228
+ "length_penalty": 1.0,
229
+ "max_length": 20,
230
+ "max_position_embeddings": 32768,
231
+ "min_length": 0,
232
+ "no_repeat_ngram_size": 0,
233
+ "num_attention_heads": 16,
234
+ "num_beam_groups": 1,
235
+ "num_beams": 1,
236
+ "num_code_groups": 16,
237
+ "num_hidden_layers": 28,
238
+ "num_key_value_heads": 8,
239
+ "num_return_sequences": 1,
240
+ "output_attentions": false,
241
+ "output_hidden_states": false,
242
+ "output_scores": false,
243
+ "pad_token_id": 151671,
244
+ "position_id_per_seconds": 13,
245
+ "prefix": null,
246
+ "problem_type": null,
247
+ "pruned_heads": {},
248
+ "remove_invalid_values": false,
249
+ "repetition_penalty": 1.0,
250
+ "return_dict": true,
251
+ "return_dict_in_generate": false,
252
+ "rms_norm_eps": 1e-06,
253
+ "rope_scaling": {
254
+ "interleaved": true,
255
+ "mrope_section": [
256
+ 24,
257
+ 20,
258
+ 20
259
+ ],
260
+ "rope_type": "default",
261
+ "type": "default"
262
+ },
263
+ "rope_theta": 1000000,
264
+ "sep_token_id": null,
265
+ "sliding_window": null,
266
+ "spk_id": {},
267
+ "spk_is_dialect": {},
268
+ "suppress_tokens": null,
269
+ "task_specific_params": null,
270
+ "temperature": 1.0,
271
+ "text_hidden_size": 2048,
272
+ "text_vocab_size": 151936,
273
+ "tf_legacy_loss": false,
274
+ "tie_encoder_decoder": false,
275
+ "tie_word_embeddings": false,
276
+ "tokenizer_class": null,
277
+ "top_k": 50,
278
+ "top_p": 1.0,
279
+ "torchscript": false,
280
+ "typical_p": 1.0,
281
+ "use_bfloat16": false,
282
+ "use_cache": true,
283
+ "use_sliding_window": false,
284
+ "vocab_size": 3072
285
+ },
286
+ "task_specific_params": null,
287
+ "temperature": 1.0,
288
+ "tf_legacy_loss": false,
289
+ "tie_encoder_decoder": false,
290
+ "tie_word_embeddings": true,
291
+ "tokenizer_class": null,
292
+ "tokenizer_type": "qwen3_tts_tokenizer_12hz",
293
+ "top_k": 50,
294
+ "top_p": 1.0,
295
+ "torchscript": false,
296
+ "transformers_version": "4.57.3",
297
+ "tts_bos_token_id": 151672,
298
+ "tts_eos_token_id": 151673,
299
+ "tts_model_size": "1b7",
300
+ "tts_model_type": "voice_design",
301
+ "tts_pad_token_id": 151671,
302
+ "typical_p": 1.0,
303
+ "use_bfloat16": false
304
+ }
generation_config.json ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "do_sample": true,
3
+ "repetition_penalty": 1.05,
4
+ "temperature": 0.9,
5
+ "top_p": 1.0,
6
+ "top_k": 50,
7
+ "subtalker_dosample": true,
8
+ "subtalker_temperature": 0.9,
9
+ "subtalker_top_p": 1.0,
10
+ "subtalker_top_k": 50,
11
+ "max_new_tokens": 8192
12
+ }
merges.txt ADDED
The diff for this file is too large to render. See raw diff
 
miner.py ADDED
@@ -0,0 +1,240 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Vocence TTS engine: Qwen3 12Hz checkpoint in the HF repo snapshot.
3
+
4
+ The chute snapshot is the only weight source: nothing is pulled from an external
5
+ model id at inference time. Optional vocence_config.yaml tweaks device, dtype,
6
+ attention, and language defaults.
7
+
8
+ This file is self-contained: transformers + qwen-tts compatibility (config
9
+ sanitization, check_model_inputs shim) is inlined so Chute does not need a
10
+ separate helper module.
11
+
12
+ Model load: Miner.__init__ -> _instantiate_qwen() -> Qwen3TTSModel.from_pretrained(repo_path).
13
+
14
+ Contract (Vocence):
15
+ Miner(path_hf_repo: Path)
16
+ warmup() -> None
17
+ generate_wav(instruction: str, text: str) -> tuple[np.ndarray, int]
18
+ """
19
+ from __future__ import annotations
20
+
21
+ import json
22
+ import threading
23
+ from pathlib import Path
24
+ from typing import Any, Mapping
25
+
26
+ import numpy as np
27
+ import transformers.utils.generic as _g
28
+
29
+ # --- Inlined from qwen3_tts_load_utils: must run before ``from qwen_tts`` (via _instantiate_qwen) ---
30
+
31
+ _apply_shim_done = False
32
+
33
+
34
+ def _apply_check_model_inputs_shim() -> None:
35
+ """qwen-tts @check_model_inputs() vs current transformers check_model_inputs factory API."""
36
+ global _apply_shim_done
37
+ if _apply_shim_done or getattr(_g, "_qwen_tts_check_model_inputs_shim_applied", False):
38
+ return
39
+ _orig = _g.check_model_inputs
40
+
41
+ def check_model_inputs(*args, **kwargs):
42
+ if not args and not kwargs:
43
+ return _orig()
44
+ if len(args) == 1 and callable(args[0]) and not kwargs:
45
+ return _orig()(args[0])
46
+ return _orig(*args, **kwargs)
47
+
48
+ _g.check_model_inputs = check_model_inputs
49
+ _g._qwen_tts_check_model_inputs_shim_applied = True
50
+ _apply_shim_done = True
51
+
52
+
53
+ _UNWANTED_DTYPE_KEYS = frozenset({"dtype", "torch_dtype"})
54
+ _NESTED_METADATA_KEYS = frozenset({"model_type"})
55
+
56
+
57
+ def _strip_config_for_qwen3_load(obj: object, depth: int = 0) -> int:
58
+ n = 0
59
+ if isinstance(obj, dict):
60
+ for k in _UNWANTED_DTYPE_KEYS:
61
+ if k in obj:
62
+ del obj[k]
63
+ n += 1
64
+ if depth > 0:
65
+ for k in _NESTED_METADATA_KEYS:
66
+ if k in obj:
67
+ del obj[k]
68
+ n += 1
69
+ for v in obj.values():
70
+ n += _strip_config_for_qwen3_load(v, depth + 1)
71
+ elif isinstance(obj, list):
72
+ for v in obj:
73
+ n += _strip_config_for_qwen3_load(v, depth)
74
+ return n
75
+
76
+
77
+ def sanitize_qwen3_tts_config_json(repo_or_config: Path) -> int:
78
+ """In-place fix for merged config.json (nested dtype / model_type keys Qwen3 sub-configs reject)."""
79
+ path = Path(repo_or_config)
80
+ if path.is_dir():
81
+ path = path / "config.json"
82
+ if not path.is_file():
83
+ return 0
84
+ with path.open("r", encoding="utf-8") as f:
85
+ data = json.load(f)
86
+ n = _strip_config_for_qwen3_load(data, 0)
87
+ if n:
88
+ with path.open("w", encoding="utf-8") as f:
89
+ json.dump(data, f, indent=2, ensure_ascii=False)
90
+ return n
91
+
92
+
93
+ _apply_check_model_inputs_shim()
94
+
95
+ # --- end inlined helpers ---
96
+
97
+ _CONFIG_NAME = "config.json"
98
+ _VOCENCE_YAML = "vocence_config.yaml"
99
+
100
+
101
+ def _merge_vocence_yaml(repo: Path) -> dict[str, Any]:
102
+ path = repo / _VOCENCE_YAML
103
+ if not path.is_file():
104
+ return {}
105
+ from yaml import safe_load
106
+
107
+ with path.open("r", encoding="utf-8") as fh:
108
+ data = safe_load(fh)
109
+ return data if isinstance(data, Mapping) else {}
110
+
111
+
112
+ def _ensure_repo_checkpoint(repo: Path) -> Path:
113
+ repo = repo.resolve()
114
+ marker = repo / _CONFIG_NAME
115
+ if not marker.is_file():
116
+ raise FileNotFoundError(
117
+ f"Model snapshot incomplete: {marker} missing. "
118
+ "Host the full Qwen3-TTS weights (checkpoint + tokenizers) in this repository."
119
+ )
120
+ return repo
121
+
122
+
123
+ def _resolve_compute_device(prefer_cuda: bool) -> str:
124
+ import torch
125
+
126
+ if prefer_cuda and torch.cuda.is_available():
127
+ return "cuda:0"
128
+ return "cpu"
129
+
130
+
131
+ def _resolve_torch_dtype(torch, prefer_bf16: bool):
132
+ if prefer_bf16 and torch.cuda.is_available():
133
+ return torch.bfloat16
134
+ return torch.float32
135
+
136
+
137
+ def _instantiate_qwen(checkpoint_dir: str, device_map: str, torch_dtype, use_flash2: bool):
138
+ """Load Qwen3TTSModel from a local directory (same call shape as example_inference / qwen-tts)."""
139
+ from qwen_tts import Qwen3TTSModel
140
+
141
+ # API: from_pretrained(path, device_map=..., dtype=..., attn_implementation=...)
142
+ # Do not use kwargs-only form with ``pretrained_model_name_or_path=``; use path as first arg.
143
+ kwargs = dict(device_map=device_map, dtype=torch_dtype, attn_implementation="sdpa")
144
+ if use_flash2:
145
+ try:
146
+ return Qwen3TTSModel.from_pretrained(
147
+ checkpoint_dir,
148
+ device_map=device_map,
149
+ dtype=torch_dtype,
150
+ attn_implementation="flash_attention_2",
151
+ )
152
+ except Exception:
153
+ # flash-attn missing or kernel mismatch — fall back to SDPA
154
+ pass
155
+ return Qwen3TTSModel.from_pretrained(checkpoint_dir, **kwargs)
156
+
157
+
158
+ def _to_mono_f32(segment: np.ndarray) -> np.ndarray:
159
+ x = np.asarray(segment, dtype=np.float32)
160
+ if x.ndim > 1:
161
+ x = x.mean(axis=1)
162
+ return x
163
+
164
+
165
+ class Miner:
166
+ """
167
+ Loads the checkpoint from the Hugging Face repo directory Chutes downloaded.
168
+ Synthesis uses natural-language instruction + text (qwen-tts API).
169
+ """
170
+
171
+ def __init__(self, path_hf_repo: Path) -> None:
172
+ self._root = _ensure_repo_checkpoint(Path(path_hf_repo))
173
+ self._cfg = _merge_vocence_yaml(self._root)
174
+ rt = self._cfg.get("runtime") or {}
175
+ gen = self._cfg.get("generation") or {}
176
+ lim = self._cfg.get("limits") or {}
177
+
178
+ self._language = str(lim.get("default_language") or rt.get("default_language", "English"))
179
+ self._output_sr = int(gen.get("sample_rate", 24000))
180
+ self._cap_instruction = int(lim.get("max_instruction_chars", 600))
181
+ self._cap_text = int(lim.get("max_text_chars", 2000))
182
+
183
+ prefer_cuda = str(rt.get("device_preference", "cuda")).lower() == "cuda"
184
+ want_bf16 = str(rt.get("dtype", "bfloat16")).lower() == "bfloat16"
185
+ flash = bool(rt.get("use_flash_attention_2", False))
186
+
187
+ import torch
188
+
189
+ device_map = _resolve_compute_device(prefer_cuda)
190
+ torch_dtype = _resolve_torch_dtype(torch, want_bf16)
191
+ ckpt = str(self._root)
192
+
193
+ # Merged HF saves may put dtype / model_type into nested sub-configs; Qwen3 rejects them.
194
+ sanitize_qwen3_tts_config_json(self._root)
195
+
196
+ self._tts = _instantiate_qwen(ckpt, device_map, torch_dtype, flash)
197
+ # Qwen3TTSModel is a thin wrapper, not nn.Module — no .eval()
198
+ print("Qwen3-TTS checkpoint ready (loaded from repo snapshot).")
199
+
200
+ def __repr__(self) -> str:
201
+ return "Miner(qwen3-tts-local, local_snapshot=True)"
202
+
203
+ def warmup(self) -> None:
204
+ """Force one cheap synthesis on a background thread (startup SLAs)."""
205
+ status: dict[str, object] = {"done": False, "error": None}
206
+
207
+ def _once() -> None:
208
+ try:
209
+ self.generate_wav(
210
+ instruction="Clear, neutral delivery.",
211
+ text="Warmup.",
212
+ )
213
+ status["done"] = True
214
+ except Exception as exc: # noqa: BLE001 — surface to host
215
+ status["error"] = str(exc)
216
+
217
+ worker = threading.Thread(target=_once, daemon=True)
218
+ worker.start()
219
+ worker.join(timeout=180.0)
220
+ if not status["done"]:
221
+ raise RuntimeError(status["error"] or "warmup exceeded 180s")
222
+
223
+ def generate_wav(self, instruction: str, text: str) -> tuple[np.ndarray, int]:
224
+ if self._cap_instruction > 0:
225
+ instruction = instruction[: self._cap_instruction]
226
+ if self._cap_text > 0:
227
+ text = text[: self._cap_text]
228
+
229
+ # Upstream qwen-tts method name (instruct + text -> waveform).
230
+ waves, sr = self._tts.generate_voice_design(
231
+ text=text,
232
+ language=self._language,
233
+ instruct=instruction,
234
+ )
235
+ if not waves:
236
+ raise ValueError("TTS generation returned no audio")
237
+ first = waves[0]
238
+ if first is None:
239
+ raise ValueError("TTS generation returned empty channel")
240
+ return _to_mono_f32(first), int(sr)
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e52ff5b60e47c4d5f32184a840f89eb684ff7562afc5b6bdab80cff01ccbbcca
3
+ size 3833402552
preprocessor_config.json ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ {
2
+ "padding_side": "left",
3
+ "padding_value": 0.0,
4
+ "processor_class": "Qwen3TTSProcessor",
5
+ "return_attention_mask": true
6
+ }
special_tokens_map.json ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "additional_special_tokens": [
3
+ "<|im_start|>",
4
+ "<|im_end|>",
5
+ "<|object_ref_start|>",
6
+ "<|object_ref_end|>",
7
+ "<|box_start|>",
8
+ "<|box_end|>",
9
+ "<|quad_start|>",
10
+ "<|quad_end|>",
11
+ "<|vision_start|>",
12
+ "<|vision_end|>",
13
+ "<|vision_pad|>",
14
+ "<|image_pad|>",
15
+ "<|video_pad|>",
16
+ "<|audio_start|>",
17
+ "<|audio_end|>",
18
+ "<tts_pad>",
19
+ "<tts_text_bos>",
20
+ "<tts_text_bos_single>",
21
+ "<|audio_pad|>"
22
+ ],
23
+ "audio_bos_token": "<|audio_start|>",
24
+ "audio_eos_token": "<|audio_end|>",
25
+ "audio_token": "<|audio_pad|>",
26
+ "eos_token": {
27
+ "content": "<|im_end|>",
28
+ "lstrip": false,
29
+ "normalized": false,
30
+ "rstrip": false,
31
+ "single_word": false
32
+ },
33
+ "image_token": "<|image_pad|>",
34
+ "pad_token": {
35
+ "content": "<|endoftext|>",
36
+ "lstrip": false,
37
+ "normalized": false,
38
+ "rstrip": false,
39
+ "single_word": false
40
+ },
41
+ "video_token": "<|video_pad|>",
42
+ "vision_bos_token": "<|vision_start|>",
43
+ "vision_eos_token": "<|vision_end|>"
44
+ }
speech_tokenizer/config.json ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "Qwen3TTSTokenizerV2Model"
4
+ ],
5
+ "model_type": "qwen3_tts_tokenizer_12hz",
6
+ "encoder_valid_num_quantizers": 16,
7
+ "input_sample_rate": 24000,
8
+ "output_sample_rate": 24000,
9
+ "decode_upsample_rate": 1920,
10
+ "encode_downsample_rate": 1920,
11
+ "decoder_config": {
12
+ "attention_bias": false,
13
+ "attention_dropout": 0.0,
14
+ "latent_dim": 1024,
15
+ "codebook_dim": 512,
16
+ "codebook_size": 2048,
17
+ "decoder_dim": 1536,
18
+ "hidden_act": "silu",
19
+ "hidden_size": 512,
20
+ "intermediate_size": 1024,
21
+ "layer_scale_initial_scale": 0.01,
22
+ "max_position_embeddings": 8000,
23
+ "head_dim": 64,
24
+ "num_attention_heads": 16,
25
+ "num_hidden_layers": 8,
26
+ "num_key_value_heads": 16,
27
+ "num_quantizers": 16,
28
+ "num_semantic_quantizers": 1,
29
+ "rms_norm_eps": 1e-05,
30
+ "rope_theta": 10000,
31
+ "semantic_codebook_size": 4096,
32
+ "sliding_window": 72,
33
+ "upsample_rates": [
34
+ 8,
35
+ 5,
36
+ 4,
37
+ 3
38
+ ],
39
+ "upsampling_ratios": [
40
+ 2,
41
+ 2
42
+ ],
43
+ "vector_quantization_hidden_dimension": 512
44
+ },
45
+ "encoder_config": {
46
+ "_frame_rate": 12.5,
47
+ "attention_bias": false,
48
+ "attention_dropout": 0.0,
49
+ "audio_channels": 1,
50
+ "codebook_dim": 256,
51
+ "codebook_size": 2048,
52
+ "compress": 2,
53
+ "dilation_growth_rate": 2,
54
+ "dtype": "float32",
55
+ "head_dim": 64,
56
+ "hidden_act": "gelu",
57
+ "hidden_size": 512,
58
+ "initializer_range": 0.02,
59
+ "intermediate_size": 2048,
60
+ "kernel_size": 7,
61
+ "last_kernel_size": 3,
62
+ "layer_scale_initial_scale": 0.01,
63
+ "max_position_embeddings": 8000,
64
+ "norm_eps": 1e-05,
65
+ "normalize": false,
66
+ "num_attention_heads": 8,
67
+ "num_filters": 64,
68
+ "num_hidden_layers": 8,
69
+ "num_key_value_heads": 8,
70
+ "num_quantizers": 32,
71
+ "num_residual_layers": 1,
72
+ "num_semantic_quantizers": 1,
73
+ "pad_mode": "constant",
74
+ "residual_kernel_size": 3,
75
+ "rope_theta": 10000.0,
76
+ "sampling_rate": 24000,
77
+ "sliding_window": 250,
78
+ "transformers_version": "4.57.0.dev0",
79
+ "trim_right_ratio": 1.0,
80
+ "upsample_groups": 512,
81
+ "upsampling_ratios": [
82
+ 8,
83
+ 6,
84
+ 5,
85
+ 4
86
+ ],
87
+ "use_cache": false,
88
+ "use_causal_conv": true,
89
+ "use_conv_shortcut": false,
90
+ "use_streaming": false,
91
+ "vector_quantization_hidden_dimension": 256
92
+ },
93
+ "transformers_version": "4.57.3"
94
+ }
speech_tokenizer/configuration.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"framework": "pytorch", "task": "feature-extraction", "allow_remote": true}
speech_tokenizer/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:836b7b357f5ea43e889936a3709af68dfe3751881acefe4ecf0dbd30ba571258
3
+ size 682293092
speech_tokenizer/preprocessor_config.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "chunk_length_s": null,
3
+ "feature_extractor_type": "EncodecFeatureExtractor",
4
+ "feature_size": 1,
5
+ "overlap": null,
6
+ "padding_side": "right",
7
+ "padding_value": 0.0,
8
+ "return_attention_mask": true,
9
+ "sampling_rate": 24000
10
+ }
tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:21cbba93fc2b3723c68db44ba5a8ff1a22a3f7bed34a5adbd5a165e17fff551c
3
+ size 11424108
tokenizer_config.json ADDED
@@ -0,0 +1,316 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_bos_token": false,
3
+ "add_prefix_space": false,
4
+ "added_tokens_decoder": {
5
+ "151643": {
6
+ "content": "<|endoftext|>",
7
+ "lstrip": false,
8
+ "normalized": false,
9
+ "rstrip": false,
10
+ "single_word": false,
11
+ "special": true
12
+ },
13
+ "151644": {
14
+ "content": "<|im_start|>",
15
+ "lstrip": false,
16
+ "normalized": false,
17
+ "rstrip": false,
18
+ "single_word": false,
19
+ "special": true
20
+ },
21
+ "151645": {
22
+ "content": "<|im_end|>",
23
+ "lstrip": false,
24
+ "normalized": false,
25
+ "rstrip": false,
26
+ "single_word": false,
27
+ "special": true
28
+ },
29
+ "151646": {
30
+ "content": "<|object_ref_start|>",
31
+ "lstrip": false,
32
+ "normalized": false,
33
+ "rstrip": false,
34
+ "single_word": false,
35
+ "special": true
36
+ },
37
+ "151647": {
38
+ "content": "<|object_ref_end|>",
39
+ "lstrip": false,
40
+ "normalized": false,
41
+ "rstrip": false,
42
+ "single_word": false,
43
+ "special": true
44
+ },
45
+ "151648": {
46
+ "content": "<|box_start|>",
47
+ "lstrip": false,
48
+ "normalized": false,
49
+ "rstrip": false,
50
+ "single_word": false,
51
+ "special": true
52
+ },
53
+ "151649": {
54
+ "content": "<|box_end|>",
55
+ "lstrip": false,
56
+ "normalized": false,
57
+ "rstrip": false,
58
+ "single_word": false,
59
+ "special": true
60
+ },
61
+ "151650": {
62
+ "content": "<|quad_start|>",
63
+ "lstrip": false,
64
+ "normalized": false,
65
+ "rstrip": false,
66
+ "single_word": false,
67
+ "special": true
68
+ },
69
+ "151651": {
70
+ "content": "<|quad_end|>",
71
+ "lstrip": false,
72
+ "normalized": false,
73
+ "rstrip": false,
74
+ "single_word": false,
75
+ "special": true
76
+ },
77
+ "151652": {
78
+ "content": "<|vision_start|>",
79
+ "lstrip": false,
80
+ "normalized": false,
81
+ "rstrip": false,
82
+ "single_word": false,
83
+ "special": true
84
+ },
85
+ "151653": {
86
+ "content": "<|vision_end|>",
87
+ "lstrip": false,
88
+ "normalized": false,
89
+ "rstrip": false,
90
+ "single_word": false,
91
+ "special": true
92
+ },
93
+ "151654": {
94
+ "content": "<|vision_pad|>",
95
+ "lstrip": false,
96
+ "normalized": false,
97
+ "rstrip": false,
98
+ "single_word": false,
99
+ "special": true
100
+ },
101
+ "151655": {
102
+ "content": "<|image_pad|>",
103
+ "lstrip": false,
104
+ "normalized": false,
105
+ "rstrip": false,
106
+ "single_word": false,
107
+ "special": true
108
+ },
109
+ "151656": {
110
+ "content": "<|video_pad|>",
111
+ "lstrip": false,
112
+ "normalized": false,
113
+ "rstrip": false,
114
+ "single_word": false,
115
+ "special": true
116
+ },
117
+ "151657": {
118
+ "content": "<tool_call>",
119
+ "lstrip": false,
120
+ "normalized": false,
121
+ "rstrip": false,
122
+ "single_word": false,
123
+ "special": false
124
+ },
125
+ "151658": {
126
+ "content": "</tool_call>",
127
+ "lstrip": false,
128
+ "normalized": false,
129
+ "rstrip": false,
130
+ "single_word": false,
131
+ "special": false
132
+ },
133
+ "151659": {
134
+ "content": "<|fim_prefix|>",
135
+ "lstrip": false,
136
+ "normalized": false,
137
+ "rstrip": false,
138
+ "single_word": false,
139
+ "special": false
140
+ },
141
+ "151660": {
142
+ "content": "<|fim_middle|>",
143
+ "lstrip": false,
144
+ "normalized": false,
145
+ "rstrip": false,
146
+ "single_word": false,
147
+ "special": false
148
+ },
149
+ "151661": {
150
+ "content": "<|fim_suffix|>",
151
+ "lstrip": false,
152
+ "normalized": false,
153
+ "rstrip": false,
154
+ "single_word": false,
155
+ "special": false
156
+ },
157
+ "151662": {
158
+ "content": "<|fim_pad|>",
159
+ "lstrip": false,
160
+ "normalized": false,
161
+ "rstrip": false,
162
+ "single_word": false,
163
+ "special": false
164
+ },
165
+ "151663": {
166
+ "content": "<|repo_name|>",
167
+ "lstrip": false,
168
+ "normalized": false,
169
+ "rstrip": false,
170
+ "single_word": false,
171
+ "special": false
172
+ },
173
+ "151664": {
174
+ "content": "<|file_sep|>",
175
+ "lstrip": false,
176
+ "normalized": false,
177
+ "rstrip": false,
178
+ "single_word": false,
179
+ "special": false
180
+ },
181
+ "151665": {
182
+ "content": "<tool_response>",
183
+ "lstrip": false,
184
+ "normalized": false,
185
+ "rstrip": false,
186
+ "single_word": false,
187
+ "special": false
188
+ },
189
+ "151666": {
190
+ "content": "</tool_response>",
191
+ "lstrip": false,
192
+ "normalized": false,
193
+ "rstrip": false,
194
+ "single_word": false,
195
+ "special": false
196
+ },
197
+ "151667": {
198
+ "content": "<think>",
199
+ "lstrip": false,
200
+ "normalized": false,
201
+ "rstrip": false,
202
+ "single_word": false,
203
+ "special": false
204
+ },
205
+ "151668": {
206
+ "content": "</think>",
207
+ "lstrip": false,
208
+ "normalized": false,
209
+ "rstrip": false,
210
+ "single_word": false,
211
+ "special": false
212
+ },
213
+ "151669": {
214
+ "content": "<|audio_start|>",
215
+ "lstrip": false,
216
+ "normalized": false,
217
+ "rstrip": false,
218
+ "single_word": false,
219
+ "special": true
220
+ },
221
+ "151670": {
222
+ "content": "<|audio_end|>",
223
+ "lstrip": false,
224
+ "normalized": false,
225
+ "rstrip": false,
226
+ "single_word": false,
227
+ "special": true
228
+ },
229
+ "151671": {
230
+ "content": "<tts_pad>",
231
+ "lstrip": false,
232
+ "normalized": false,
233
+ "rstrip": false,
234
+ "single_word": false,
235
+ "special": true
236
+ },
237
+ "151672": {
238
+ "content": "<tts_text_bos>",
239
+ "lstrip": false,
240
+ "normalized": false,
241
+ "rstrip": false,
242
+ "single_word": false,
243
+ "special": true
244
+ },
245
+ "151673": {
246
+ "content": "<tts_text_eod>",
247
+ "lstrip": false,
248
+ "normalized": false,
249
+ "rstrip": false,
250
+ "single_word": false,
251
+ "special": true
252
+ },
253
+ "151674": {
254
+ "content": "<tts_text_bos_single>",
255
+ "lstrip": false,
256
+ "normalized": false,
257
+ "rstrip": false,
258
+ "single_word": false,
259
+ "special": true
260
+ },
261
+ "151675": {
262
+ "content": "<|audio_pad|>",
263
+ "lstrip": false,
264
+ "normalized": false,
265
+ "rstrip": false,
266
+ "single_word": false,
267
+ "special": true
268
+ }
269
+ },
270
+ "additional_special_tokens": [
271
+ "<|im_start|>",
272
+ "<|im_end|>",
273
+ "<|object_ref_start|>",
274
+ "<|object_ref_end|>",
275
+ "<|box_start|>",
276
+ "<|box_end|>",
277
+ "<|quad_start|>",
278
+ "<|quad_end|>",
279
+ "<|vision_start|>",
280
+ "<|vision_end|>",
281
+ "<|vision_pad|>",
282
+ "<|image_pad|>",
283
+ "<|video_pad|>",
284
+ "<|audio_start|>",
285
+ "<|audio_end|>",
286
+ "<tts_pad>",
287
+ "<tts_text_bos>",
288
+ "<tts_text_bos_single>",
289
+ "<|audio_pad|>"
290
+ ],
291
+ "extra_special_tokens": {
292
+ "image_token": "<|image_pad|>",
293
+ "audio_token": "<|audio_pad|>",
294
+ "video_token": "<|video_pad|>",
295
+ "vision_bos_token": "<|vision_start|>",
296
+ "vision_eos_token": "<|vision_end|>",
297
+ "audio_bos_token": "<|audio_start|>",
298
+ "audio_eos_token": "<|audio_end|>"
299
+ },
300
+ "bos_token": null,
301
+ "clean_up_tokenization_spaces": false,
302
+ "eos_token": "<|im_end|>",
303
+ "errors": "replace",
304
+ "model_max_length": 131072,
305
+ "pad_token": "<|endoftext|>",
306
+ "split_special_tokens": false,
307
+ "tokenizer_class": "Qwen2Tokenizer",
308
+ "unk_token": null,
309
+ "image_token": "<|image_pad|>",
310
+ "audio_token": "<|audio_pad|>",
311
+ "video_token": "<|video_pad|>",
312
+ "vision_bos_token": "<|vision_start|>",
313
+ "vision_eos_token": "<|vision_end|>",
314
+ "audio_bos_token": "<|audio_start|>",
315
+ "audio_eos_token": "<|audio_end|>"
316
+ }
vocab.json ADDED
The diff for this file is too large to render. See raw diff
 
vocence_config.yaml ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Miner + /health metadata. Weights live in this HF repo (no runtime model_id).
2
+ runtime:
3
+ adapter: "qwen3_tts_repo_snapshot"
4
+ device_preference: "cuda"
5
+ dtype: "bfloat16"
6
+ default_language: "English"
7
+ use_flash_attention_2: false
8
+
9
+ generation:
10
+ sample_rate: 24000
11
+ max_seconds: 30
12
+
13
+ limits:
14
+ max_text_chars: 2000
15
+ max_instruction_chars: 600
16
+ default_language: "English"