Instructions to use anke01/qwen3-tts-uyghur with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use anke01/qwen3-tts-uyghur with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-to-speech", model="anke01/qwen3-tts-uyghur")# pip install -U transformers accelerate # Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("anke01/qwen3-tts-uyghur", device_map="auto") - Notebooks
- Google Colab
- Kaggle
Download prepare_data.py from anke01/qwen3-tts-uyghur: direct link, hf CLI and curl.
- Browser
- Download file 5.84 kB
-
https://huggingface.co/anke01/qwen3-tts-uyghur/resolve/main/prepare_data.py
- Command line
-
hf download hf://anke01/qwen3-tts-uyghur/prepare_data.py
-
curl -L -o prepare_data.py https://huggingface.co/anke01/qwen3-tts-uyghur/resolve/main/prepare_data.py
5.84 kB
| # coding=utf-8 | |
| # Copyright 2025 The Alibaba Qwen team. | |
| # SPDX-License-Identifier: Apache-2.0 | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| """ | |
| Qwen3-TTS-12Hz Audio Codes 提取脚本 (优化版) | |
| 修复内容: | |
| 1. 使用逐行读取,减少内存占用 | |
| 2. 添加异常处理,跳过损坏的音频文件 | |
| 3. 修复最后一个 batch 处理逻辑(合并到主 with 块) | |
| 4. 修复进度条更新(最后一个 batch 使用实际数量) | |
| 5. 添加 --batch_size 参数动态调整 | |
| Usage: | |
| python prepare_data.py \ | |
| --device cuda:0 \ | |
| --tokenizer_model_path Qwen/Qwen3-TTS-Tokenizer-12Hz \ | |
| --input_jsonl ./processed_data/uyghur_all/train_raw.jsonl \ | |
| --output_jsonl ./processed_data/uyghur_all/train_with_codes.jsonl | |
| """ | |
| import argparse | |
| import json | |
| import os | |
| import sys | |
| from tqdm import tqdm | |
| from qwen_tts import Qwen3TTSTokenizer | |
| BATCH_INFER_NUM = 32 | |
| SAVE_INTERVAL = 5000 # Save every N samples | |
| def main(): | |
| parser = argparse.ArgumentParser(description='Extract audio codes (优化版)') | |
| parser.add_argument("--device", type=str, default="cuda:0") | |
| parser.add_argument("--tokenizer_model_path", type=str, default="Qwen/Qwen3-TTS-Tokenizer-12Hz") | |
| parser.add_argument("--input_jsonl", type=str, required=True) | |
| parser.add_argument("--output_jsonl", type=str, required=True) | |
| parser.add_argument("--batch_size", type=int, default=BATCH_INFER_NUM, | |
| help=f"批次大小 (default: {BATCH_INFER_NUM})") | |
| args = parser.parse_args() | |
| print(f"Loading tokenizer from: {args.tokenizer_model_path}") | |
| tokenizer_12hz = Qwen3TTSTokenizer.from_pretrained( | |
| args.tokenizer_model_path, | |
| device_map=args.device, | |
| ) | |
| print(f"Tokenizer loaded successfully on {args.device}") | |
| # 修复:使用逐行读取,减少内存占用 | |
| print(f"Reading input file: {args.input_jsonl}") | |
| total_count = 0 | |
| with open(args.input_jsonl, 'r', encoding='utf-8') as f: | |
| for _ in f: | |
| total_count += 1 | |
| print(f"Total samples: {total_count:,}") | |
| # 创建输出目录 | |
| output_dir = os.path.dirname(args.output_jsonl) | |
| if output_dir and not os.path.exists(output_dir): | |
| os.makedirs(output_dir, exist_ok=True) | |
| processed_count = 0 | |
| failed_count = 0 | |
| batch_size = args.batch_size | |
| print(f"Processing with batch_size={batch_size}...") | |
| # 修复:统一在单个 with 块内处理所有数据 | |
| with open(args.output_jsonl, 'w', encoding='utf-8') as f: | |
| batch_lines = [] | |
| batch_audios = [] | |
| pbar = tqdm(total=total_count, desc="Extracting audio codes") | |
| # 逐行读取并处理 | |
| with open(args.input_jsonl, 'r', encoding='utf-8') as infile: | |
| for line in infile: | |
| try: | |
| line_data = json.loads(line.strip()) | |
| batch_lines.append(line_data) | |
| batch_audios.append(line_data['audio']) | |
| except Exception as e: | |
| print(f"Warning: Failed to parse line: {e}") | |
| failed_count += 1 | |
| pbar.update(1) | |
| continue | |
| # 达到批次大小时处理 | |
| if len(batch_lines) >= batch_size: | |
| try: | |
| enc_res = tokenizer_12hz.encode(batch_audios) | |
| for code, line_data in zip(enc_res.audio_codes, batch_lines): | |
| line_data['audio_codes'] = code.cpu().tolist() | |
| f.write(json.dumps(line_data, ensure_ascii=False) + '\n') | |
| processed_count += 1 | |
| except Exception as e: | |
| print(f"Warning: Failed to encode batch: {e}") | |
| failed_count += len(batch_lines) | |
| batch_lines.clear() | |
| batch_audios.clear() | |
| pbar.update(batch_size) | |
| # 定期显示进度 | |
| if processed_count % SAVE_INTERVAL == 0: | |
| print(f" Progress: {processed_count:,} / {total_count:,} ({100*processed_count/total_count:.1f}%)") | |
| # 修复:处理剩余的最后一个 batch(在主 with 块内) | |
| if len(batch_audios) > 0: | |
| try: | |
| enc_res = tokenizer_12hz.encode(batch_audios) | |
| for code, line_data in zip(enc_res.audio_codes, batch_lines): | |
| line_data['audio_codes'] = code.cpu().tolist() | |
| f.write(json.dumps(line_data, ensure_ascii=False) + '\n') | |
| processed_count += 1 | |
| except Exception as e: | |
| print(f"Warning: Failed to encode final batch: {e}") | |
| failed_count += len(batch_lines) | |
| # 修复:使用实际数量更新进度条 | |
| pbar.update(len(batch_lines)) | |
| batch_lines.clear() | |
| batch_audios.clear() | |
| pbar.close() | |
| print(f"\n{'='*60}") | |
| print(f"Done!") | |
| print(f" Total samples: {total_count:,}") | |
| print(f" Processed: {processed_count:,}") | |
| print(f" Failed: {failed_count:,}") | |
| print(f" Success rate: {100*processed_count/(processed_count+failed_count):.1f}%") | |
| print(f"Output saved to: {args.output_jsonl}") | |
| print(f"{'='*60}") | |
| if __name__ == "__main__": | |
| main() | |