groq-Kokoro / app.py
haouarin's picture
Create app.py
2c2660b verified
Raw
History Blame Contribute Delete
5.83 kB
import argparse
import os
import soundfile as sf
import gradio as gr
import numpy as np
from groq import Groq
from models import build_model
from kokoro import generate
import torch
### NEW: We'll store the default voice name in a global variable so we can change it later.
DEFAULT_VOICE_NAME = 'bm_george'
def initialize_model():
device = 'cuda' if torch.cuda.is_available() else 'cpu'
model = build_model('/content/Kokoro-82M/fp16/kokoro-v0_19-half.pth', device)
### UPDATED: Use our DEFAULT_VOICE_NAME here, so we can swap it out later
voice_name = DEFAULT_VOICE_NAME
voicepack = torch.load(f'voices/{voice_name}.pt', weights_only=True).to(device)
print(f'Loaded voice: {voice_name}')
return model, voicepack, device
MODEL, VOICEPACK, DEVICE = initialize_model()
client = None
def initialize_groq(api_key):
"""
Initialize the Groq client with the provided API key.
"""
global client
try:
client = Groq(api_key=api_key)
return "API key configured successfully"
except Exception as e:
return f"Error configuring API key: {str(e)}"
### NEW: Function to change voice pack after the program has started
def set_voice_name(voice):
"""
Dynamically load the requested voicepack.
"""
global VOICEPACK, DEFAULT_VOICE_NAME
try:
VOICEPACK = torch.load(f'voices/{voice}.pt', weights_only=True).to(DEVICE)
DEFAULT_VOICE_NAME = voice # store new default so we can keep track
return f"Voice changed to {voice}"
except FileNotFoundError:
return f"Voice pack {voice} not found in voices/"
def answer(question):
if not client:
return "Please configure Groq API key first"
try:
chat_completion = client.chat.completions.create(
messages=[
{
"role": "system",
"content": "you are a helpful assistant. your answers must be short"
},
{
"role": "user",
"content": question
}
],
model="llama3-8b-8192",
temperature=0.5,
max_tokens=1024,
top_p=1,
stop=None,
stream=False,
)
return chat_completion.choices[0].message.content
except Exception as e:
return f"Error: {str(e)}"
def conversation_pipeline(audio_path=None, text_input=None):
if not client:
return "Please configure Groq API key first", None, None
if audio_path and os.path.exists(audio_path):
with open(audio_path, "rb") as file:
transcription = client.audio.transcriptions.create(
file=(audio_path, file.read()),
model="distil-whisper-large-v3-en",
response_format="verbose_json",
).text
elif text_input:
transcription = text_input
else:
return None, None, None
gemini_response = answer(transcription)
generated_audio, _ = generate(MODEL, gemini_response, VOICEPACK, lang="a")
return transcription, gemini_response, generated_audio
def process_audio(audio=None, text_input=None):
if audio is not None:
audio_path = "temp_audio.wav"
sf.write(audio_path, audio[1], audio[0])
transcription, response, audio_out = conversation_pipeline(audio_path=audio_path)
os.remove(audio_path)
else:
transcription, response, audio_out = conversation_pipeline(text_input=text_input)
if audio_out is not None:
audio_out = np.array(audio_out).flatten().astype(np.float32)
return (
transcription if transcription else "",
response if response else "",
(24000, audio_out),
)
return "", "", None
def main():
with gr.Blocks() as interface:
gr.Markdown("# Voice Chat Interface")
gr.Markdown("Configure API key and start chatting")
# Row for API key
with gr.Row():
api_key = gr.Textbox(label="Groq API Key", type="password")
api_status = gr.Textbox(label="API Status", interactive=False)
configure_btn = gr.Button("Configure API")
### NEW: Row to change voice name on the fly
with gr.Row():
voice_name_input = gr.Textbox(label="Voice Name", value=DEFAULT_VOICE_NAME)
voice_status = gr.Textbox(label="Voice Status", interactive=False)
set_voice_btn = gr.Button("Set Voice")
# Row for user input
with gr.Row():
audio_input = gr.Audio(sources=["microphone"], type="numpy", label="Speak")
text_input = gr.Textbox(label="Or type your message here")
# Row for outputs
with gr.Row():
transcription = gr.Textbox(label="Transcription", interactive=False)
response = gr.Textbox(label="AI Response", interactive=False)
with gr.Row():
audio_output = gr.Audio(label="AI Voice Response", autoplay=True)
# Configure API key
configure_btn.click(
initialize_groq,
inputs=[api_key],
outputs=[api_status]
)
### NEW: Set voice dynamically
set_voice_btn.click(
set_voice_name,
inputs=[voice_name_input],
outputs=[voice_status]
)
# Process with either audio or text
audio_input.change(
process_audio,
inputs=[audio_input, text_input],
outputs=[transcription, response, audio_output]
)
text_input.submit(
process_audio,
inputs=[audio_input, text_input],
outputs=[transcription, response, audio_output]
)
interface.launch(share=True)
if __name__ == "__main__":
main()