1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
| docker run --rm -i \
-v ${INDEX_TTS_WORK}/code/index-tts:/workspace \
-w /workspace \
indextts-ascend:v0.1 \
python3 - <<'PY'
from pathlib import Path
def replace_once(text, old, new, label):
if new in text:
return text
if old not in text:
raise SystemExit(f"patch failed: {label}")
return text.replace(old, new, 1)
infer_path = Path("indextts/infer_v2.py")
infer = infer_path.read_text()
infer = replace_once(
infer,
"import librosa\nimport torch\nimport torchaudio\n",
"import librosa\nimport torch\ntry:\n import torch_npu # noqa: F401\nexcept Exception:\n torch_npu = None\nimport torchaudio\n",
"import torch_npu",
)
infer = replace_once(
infer,
"from transformers import SeamlessM4TFeatureExtractor\nimport random\nimport torch.nn.functional as F\n",
"from transformers import SeamlessM4TFeatureExtractor\nimport random\nimport torch.nn.functional as F\n\n\ndef empty_device_cache():\n if hasattr(torch, \"npu\") and torch.npu.is_available():\n torch.npu.empty_cache()\n elif torch.cuda.is_available():\n torch.cuda.empty_cache()\n",
"empty_device_cache",
)
infer = replace_once(
infer,
' elif hasattr(torch, "xpu") and torch.xpu.is_available():\n self.device = "xpu"\n self.use_fp16 = use_fp16\n self.use_cuda_kernel = False\n',
' elif hasattr(torch, "npu") and torch.npu.is_available():\n self.device = "npu:0"\n self.use_fp16 = use_fp16\n self.use_cuda_kernel = False\n elif hasattr(torch, "xpu") and torch.xpu.is_available():\n self.device = "xpu"\n self.use_fp16 = use_fp16\n self.use_cuda_kernel = False\n',
"npu device select",
)
infer = replace_once(
infer,
" self.qwen_emo = QwenEmotion(os.path.join(self.model_dir, self.cfg.qwen_emo_path))\n",
" self.qwen_emo = QwenEmotion(os.path.join(self.model_dir, self.cfg.qwen_emo_path), device=self.device)\n",
"qwen emotion device",
)
cache_call = " torch.cuda.empty_cache()"
if cache_call in infer:
infer = infer.replace(cache_call, " empty_device_cache()")
elif " empty_device_cache()" not in infer:
raise SystemExit("patch failed: empty cache replacement")
infer = replace_once(
infer,
" feat = torchaudio.compliance.kaldi.fbank(audio_16k.to(ref_mel.device),\n num_mel_bins=80,\n dither=0,\n sample_frequency=16000)\n",
" feat = torchaudio.compliance.kaldi.fbank(\n audio_16k.cpu(),\n num_mel_bins=80,\n dither=0,\n sample_frequency=16000,\n ).to(ref_mel.device)\n",
"kaldi fbank cpu",
)
infer = replace_once(
infer,
'class QwenEmotion:\n def __init__(self, model_dir):\n self.model_dir = model_dir\n self.tokenizer = AutoTokenizer.from_pretrained(self.model_dir)\n self.model = AutoModelForCausalLM.from_pretrained(\n self.model_dir,\n torch_dtype="float16", # "auto"\n device_map="auto"\n )\n self.prompt = "文本情感分类"\n',
'class QwenEmotion:\n def __init__(self, model_dir, device=None):\n self.model_dir = model_dir\n self.tokenizer = AutoTokenizer.from_pretrained(self.model_dir)\n dtype = torch.float16 if device and device != "cpu" else torch.float32\n self.model = AutoModelForCausalLM.from_pretrained(\n self.model_dir,\n torch_dtype=dtype,\n )\n if device and device != "cpu":\n self.model = self.model.to(device)\n self.model.eval()\n self.prompt = "文本情感分类"\n',
"QwenEmotion init",
)
infer_path.write_text(infer)
webui_path = Path("webui.py")
webui = webui_path.read_text()
webui = replace_once(
webui,
'parser.add_argument("--model_dir", type=str, default="./checkpoints", help="Model checkpoints directory")\nparser.add_argument("--fp16", action="store_true", default=False, help="Use FP16 for inference if available")\n',
'parser.add_argument("--model_dir", type=str, default="./checkpoints", help="Model checkpoints directory")\nparser.add_argument("--device", type=str, default=None, help="Device to run on, for example npu:0, cuda:0, cpu")\nparser.add_argument("--fp16", action="store_true", default=False, help="Use FP16 for inference if available")\n',
"webui device argument",
)
webui = replace_once(
webui,
" use_deepspeed=cmd_args.deepspeed,\n use_cuda_kernel=cmd_args.cuda_kernel,\n )\n",
" use_deepspeed=cmd_args.deepspeed,\n use_cuda_kernel=cmd_args.cuda_kernel,\n device=cmd_args.device,\n )\n",
"webui device pass",
)
webui_path.write_text(webui)
front_path = Path("indextts/utils/front.py")
front = front_path.read_text()
front = replace_once(
front,
''' import platform
if self.zh_normalizer is not None and self.en_normalizer is not None:
return
if platform.system() != "Linux": # Mac and Windows
from wetext import Normalizer
self.zh_normalizer = Normalizer(remove_erhua=False, lang="zh", operator="tn")
self.en_normalizer = Normalizer(lang="en", operator="tn")
else:
from tn.chinese.normalizer import Normalizer as NormalizerZh
from tn.english.normalizer import Normalizer as NormalizerEn
# use new cache dir for build tagger rules with disable remove_interjections and remove_erhua
cache_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "tagger_cache")
if not os.path.exists(cache_dir):
os.makedirs(cache_dir)
with open(os.path.join(cache_dir, ".gitignore"), "w") as f:
f.write("*\\n")
self.zh_normalizer = NormalizerZh(
cache_dir=cache_dir, remove_interjections=False, remove_erhua=False, overwrite_cache=False
)
self.en_normalizer = NormalizerEn(overwrite_cache=False)
''',
''' if self.zh_normalizer is not None and self.en_normalizer is not None:
return
from wetext import Normalizer
self.zh_normalizer = Normalizer(
remove_interjections=False,
remove_erhua=False,
lang="zh",
operator="tn",
)
self.en_normalizer = Normalizer(lang="en", operator="tn")
''',
"wetext runtime",
)
front_path.write_text(front)
print("IndexTTS2 Ascend patch applied.")
PY
|