File size: 4,198 Bytes
abd39d3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""Real CT2 translation + Piper CUDA session and short synthesis smoke check."""
import argparse
import io
import json
import sys
import time
import wave
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parents[1]))


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--model', default='HachimiMT-60-QT')
    parser.add_argument('--voice', default='ngochuyennew')
    parser.add_argument('--tts-engine',choices=['piper','vieneu'],default='piper')
    args = parser.parse_args()
    from translation.core.ct2_safe_import import import_ctranslate2
    ct2 = import_ctranslate2()
    import importlib.metadata
    import ctypes
    for package in ('onnxruntime-gpu', 'nvidia-cudnn-cu12', 'ctranslate2', 'piper-tts'):
        try:
            print(f'{package}={importlib.metadata.version(package)}', flush=True)
        except importlib.metadata.PackageNotFoundError:
            print(f'{package}=not-installed', flush=True)
    try:
        cudnn = ctypes.CDLL('libcudnn.so.9')
        cudnn.cudnnGetVersion.restype = ctypes.c_size_t
        print(f'loaded_cudnn_version={cudnn.cudnnGetVersion()}', flush=True)
    except OSError as exc:
        print(f'cuDNN load check: {exc}', flush=True)
    if ct2.get_cuda_device_count() < 1:
        raise RuntimeError('CT2 không thấy GPU. Chọn runtime T4 và kiểm tra nvidia-smi.')
    from translation.engines import LocalEngine
    engine = LocalEngine(args.model, backend='ct2')
    engine.load()
    output = engine.translate_raw(['你好世界。'], beam_size=2)
    device = engine.translator.device if engine.translator is not None else engine.model.device
    if device != 'cuda':
        raise RuntimeError(f'CT2 đang chạy {device}, không phải CUDA')
    # Release translation model before checking voice to keep smoke-test simple.
    del engine
    if args.tts_engine=='vieneu':
        import tempfile,os
        import soundfile as sf
        from audio.vieneu_service import synthesize_to_wav,get_runtime,runtime_status
        os.environ['VIENEU_DEVICE']='cuda';before=time.perf_counter()
        with tempfile.TemporaryDirectory() as work:
            path=Path(work)/'smoke.wav'
            synthesize_to_wav('Xin chào, kiểm tra giọng đọc trên GPU.',args.voice,path)
            samples,rate=sf.read(path)
        if get_runtime().backend!='pytorch' or len(samples)==0 or rate!=48000:
            raise RuntimeError('VieNeu GPU không trả về WAV 48 kHz hợp lệ.')
        print(json.dumps({'ct2_device':device,'translation_sample':output,'tts':runtime_status(),'audio_seconds':len(samples)/rate,'synthesis_seconds':time.perf_counter()-before},ensure_ascii=False))
        return
    from audio.audio_service import get_voice, tts_runtime_status
    from tts.synthesis import synthesize_wav
    voice = get_voice(args.voice)
    providers = voice.session.get_providers()
    if 'CUDAExecutionProvider' not in providers:
        raise RuntimeError(f'Piper session không dùng CUDA: {providers}')
    # Separate WAVs because Piper sets WAV parameters on each synthesis call.
    before = time.perf_counter()
    durations = []
    for text in ('Xin chào, kiểm tra giọng đọc trên GPU.',
                 ('người lữ hành bước qua khu rừng và nhìn về phía chân trời ' * 20).strip()):
        buffer = io.BytesIO()
        with wave.open(buffer, 'wb') as wav:
            synthesize_wav(voice, text, wav)
        with wave.open(io.BytesIO(buffer.getvalue()), 'rb') as wav:
            durations.append(wav.getnframes() / wav.getframerate())
    duration = sum(durations)
    if 'CUDAExecutionProvider' not in voice.session.get_providers():
        raise RuntimeError('Piper rơi về CPU sau inference')
    print(json.dumps({'ct2_device': device, 'translation_sample': output,
                      'tts': tts_runtime_status(), 'audio_seconds': duration,
                      'synthesis_seconds': round(time.perf_counter() - before, 3)},
                     ensure_ascii=False, indent=2))
    if any(value <= 0 for value in durations):
        raise RuntimeError('Piper trả về audio rỗng')


if __name__ == '__main__':
    main()