File size: 4,623 Bytes
5d66ca8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import spaces
from kokoro import KModel, KPipeline
import gradio as gr
import os
import random
import torch

# GPU Kullanımını KAPATIYORUZ
CUDA_AVAILABLE = False  # GPU'yu tamamen devre dışı bırak
CHAR_LIMIT = 5000  # Karakter limiti (isteğe bağlı)

# Modelleri Yükle (SADECE CPU Kullanacak)
models = {False: KModel().to('cpu').eval()}  
pipelines = {lang_code: KPipeline(lang_code=lang_code, model=False) for lang_code in 'ab'}
pipelines['a'].g2p.lexicon.golds['kokoro'] = 'kˈOkəɹO'
pipelines['b'].g2p.lexicon.golds['kokoro'] = 'kˈQkəɹQ'

# GPU Fonksiyonunu Kaldırıyoruz
def forward_cpu(ps, ref_s, speed):
    return models[False](ps, ref_s, speed)

# Ses Üretme Fonksiyonu (Tamamen CPU Kullanır)
def generate_first(text, voice='af_heart', speed=1):
    text = text.strip()[:CHAR_LIMIT]  # Karakter limitini uygula
    pipeline = pipelines[voice[0]]
    pack = pipeline.load_voice(voice)

    for _, ps, _ in pipeline(text, voice, speed):
        ref_s = pack[len(ps)-1]
        try:
            audio = forward_cpu(ps, ref_s, speed)  # SADECE CPU Kullan
        except Exception as e:
            raise gr.Error(e)
        return (24000, audio.numpy()), ps
    return None, ''

# Arena API
def predict(text, voice='af_heart', speed=1):
    return generate_first(text, voice, speed)[0]

# Tokenizasyon Fonksiyonu
def tokenize_first(text, voice='af_heart'):
    pipeline = pipelines[voice[0]]
    for _, ps, _ in pipeline(text, voice):
        return ps
    return ''

# Akış Modu İçin CPU Kullanımı
def generate_all(text, voice='af_heart', speed=1):
    text = text.strip()[:CHAR_LIMIT]
    pipeline = pipelines[voice[0]]
    pack = pipeline.load_voice(voice)

    for _, ps, _ in pipeline(text, voice, speed):
        ref_s = pack[len(ps)-1]
        try:
            audio = forward_cpu(ps, ref_s, speed)  # SADECE CPU Kullan
        except Exception as e:
            raise gr.Error(e)
        yield 24000, audio.numpy()

# Rastgele Metin Getirme
random_texts = {'en': ["Hello, this is a test.", "How are you?", "Welcome to Kokoro!"]}
def get_random_text(voice):
    return random.choice(random_texts['en'])

# Ses Seçenekleri
CHOICES = {
    '🇺🇸 🚺 Heart ❤️': 'af_heart',
    '🇺🇸 🚺 Bella 🔥': 'af_bella',
    '🇺🇸 🚺 Nicole 🎧': 'af_nicole',
    '🇺🇸 🚹 Michael': 'am_michael',
    '🇬🇧 🚺 Emma': 'bf_emma',
    '🇬🇧 🚹 George': 'bm_george',
}
for v in CHOICES.values():
    pipelines[v[0]].load_voice(v)

# Token Bilgilendirme
TOKEN_NOTE = '''
💡 Özelleştirilmiş telaffuz için /slashes/ kullanabilirsiniz.
'''

# Arayüz - Generate Sekmesi
with gr.Blocks() as generate_tab:
    out_audio = gr.Audio(label='Çıktı Sesi', interactive=False, autoplay=True)
    generate_btn = gr.Button('Oluştur', variant='primary')
    with gr.Accordion('Çıktı Tokenleri', open=True):
        out_ps = gr.Textbox(interactive=False, show_label=False, info='Ses üretiminde kullanılan tokenler.')
        tokenize_btn = gr.Button('Tokenize', variant='secondary')

# Arayüz - Akış Sekmesi
with gr.Blocks() as stream_tab:
    out_stream = gr.Audio(label='Canlı Akış Sesi', interactive=False, streaming=True, autoplay=True)
    with gr.Row():
        stream_btn = gr.Button('Akışı Başlat', variant='primary')
        stop_btn = gr.Button('Durdur', variant='stop')

# Ana Arayüz
BANNER_TEXT = '***Kokoro*** **82M parametreli açık kaynak TTS modelidir.**'
with gr.Blocks() as app:
    with gr.Row():
        gr.Markdown(BANNER_TEXT, container=True)
    with gr.Row():
        with gr.Column():
            text = gr.Textbox(label='Metin Girişi', info=f"En fazla {CHAR_LIMIT} karakter")
            with gr.Row():
                voice = gr.Dropdown(list(CHOICES.items()), value='af_heart', label='Ses Seçimi')
            speed = gr.Slider(minimum=0.5, maximum=2, value=1, step=0.1, label='Konuşma Hızı')
            random_btn = gr.Button('Rastgele Metin', variant='secondary')
        with gr.Column():
            gr.TabbedInterface([generate_tab, stream_tab], ['Oluştur', 'Akış'])
    
    # Buton Bağlantıları
    random_btn.click(fn=get_random_text, inputs=[voice], outputs=[text])
    generate_btn.click(fn=generate_first, inputs=[text, voice, speed], outputs=[out_audio, out_ps])
    tokenize_btn.click(fn=tokenize_first, inputs=[text, voice], outputs=[out_ps])
    stream_event = stream_btn.click(fn=generate_all, inputs=[text, voice, speed], outputs=[out_stream])
    stop_btn.click(fn=None, cancels=stream_event)

# Uygulamayı Başlat
if __name__ == '__main__':
    app.queue().launch(show_api=True, ssr_mode=True)