Spaces:
Running
on
Zero
Running
on
Zero
File size: 6,016 Bytes
87930ea 94540c3 87930ea 94540c3 87930ea 4898006 87930ea 3268a02 87930ea 3268a02 b164fe5 3268a02 87930ea 3268a02 87930ea b164fe5 87930ea 4898006 b164fe5 87930ea b164fe5 87930ea 64e2453 87930ea 5d37f08 7a52d3b 5d37f08 bf9ca9b 5d37f08 87930ea 3268a02 5d37f08 3268a02 87930ea 5d37f08 7a52d3b bf9ca9b 7a52d3b bf9ca9b 5d37f08 4b2b7f5 5d37f08 87930ea b164fe5 87930ea b164fe5 87930ea b164fe5 94540c3 87930ea b164fe5 87930ea b164fe5 52385ae b164fe5 87930ea b164fe5 87930ea b164fe5 87930ea 94540c3 |
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 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
import time
import traceback
from dataclasses import dataclass, field
import gradio as gr
import librosa
import numpy as np
import soundfile as sf
import spaces
import torch
import xxhash
from datasets import Audio
from transformers import AutoModel
import io
if gr.NO_RELOAD:
diva_model = AutoModel.from_pretrained(
"WillHeld/DiVA-llama-3-v0-8b", trust_remote_code=True
)
resampler = Audio(sampling_rate=16_000)
@spaces.GPU
@torch.no_grad
def diva_audio(audio_input, do_sample=False, temperature=0.001, prev_outs=None):
sr, y = audio_input
x = xxhash.xxh32(bytes(y)).hexdigest()
y = y.astype(np.float32)
y /= np.max(np.abs(y))
a = resampler.decode_example(
resampler.encode_example({"array": y, "sampling_rate": sr})
)
yield from diva_model.generate_stream(
a["array"],
(
"Your name is DiVA, which stands for Distilled Voice Assistant. You were trained with early-fusion training to merge OpenAI's Whisper and Meta AI's Llama 3 8B to provide end-to-end voice processing. You should give brief and helpful answers, in a conversational style. The user is talking to you with their voice and you are responding with text."
if prev_outs == None
else None
),
do_sample=do_sample,
max_new_tokens=256,
init_outputs=prev_outs,
return_outputs=True,
)
@dataclass
class AppState:
stream: np.ndarray | None = None
sampling_rate: int = 0
stopped: bool = False
conversation: list = field(default_factory=list)
model_outs: any = None
def process_audio(audio: tuple, state: AppState):
return audio, state
@spaces.GPU(duration=40, progress=gr.Progress(track_tqdm=True))
def response(state: AppState, audio: tuple):
if not audio:
return AppState()
state.stream = audio[1]
state.sampling_rate = audio[0]
file_name = f"/tmp/{xxhash.xxh32(bytes(state.stream)).hexdigest()}.wav"
sf.write(file_name, state.stream, state.sampling_rate, format="wav")
state.conversation.append(
{"role": "user", "content": {"path": file_name, "mime_type": "audio/wav"}}
)
if spaces.config.Config.zero_gpu:
if state.model_outs is not None:
state.model_outs.past_key_values = tuple(
tuple(torch.tensor(vec).cuda() for vec in tup)
for tup in state.model_outs.past_key_values
)
print(outs)
prev_outs = state.model_outs
start = False
for resp, outs in diva_audio(
(state.sampling_rate, state.stream),
prev_outs=(prev_out if state.model_outs is not None is not None else None),
):
if not start:
state.conversation.append({"role": "assistant", "content": resp})
start = True
else:
state.conversation[-1]["content"] = resp
# yield state, state.conversation
del outs.logits
del outs.hidden_states
if spaces.config.Config.zero_gpu:
outs.past_key_values = tuple(
tuple(vec.cpu().numpy() for vec in tup) for tup in outs.past_key_values
)
print(outs)
return (
AppState(conversation=state.conversation),
state.conversation,
)
def start_recording_user(state: AppState):
return None
theme = gr.themes.Soft(
primary_hue=gr.themes.Color(
c100="#82000019",
c200="#82000033",
c300="#8200004c",
c400="#82000066",
c50="#8200007f",
c500="#8200007f",
c600="#82000099",
c700="#820000b2",
c800="#820000cc",
c900="#820000e5",
c950="#820000f2",
),
secondary_hue="rose",
neutral_hue="stone",
)
js = """
async function main() {
const script1 = document.createElement("script");
script1.src = "https://cdn.jsdelivr.net/npm/onnxruntime-web@1.14.0/dist/ort.js";
document.head.appendChild(script1)
const script2 = document.createElement("script");
script2.onload = async () => {
console.log("vad loaded") ;
var record = document.querySelector('.record-button');
record.textContent = "Just Start Talking!"
record.style = "width: 11vw"
const myvad = await vad.MicVAD.new({
onSpeechStart: () => {
var record = document.querySelector('.record-button');
if (record != null) {
console.log(record);
record.click();
}
},
onSpeechEnd: (audio) => {
var stop = document.querySelector('.stop-button');
if (stop != null) {
console.log(stop);
stop.click();
}
}
})
myvad.start()
}
script2.src = "https://cdn.jsdelivr.net/npm/@ricky0123/vad-web@0.0.7/dist/bundle.min.js";
script1.onload = () => {
console.log("onnx loaded")
document.head.appendChild(script2)
};
}
"""
js_reset = """
() => {
var record = document.querySelector('.record-button');
record.textContent = "Just Start Talking!"
record.style = "width: 11vw"
}
"""
with gr.Blocks(theme=theme, js=js) as demo:
with gr.Row():
input_audio = gr.Audio(
label="Input Audio",
sources=["microphone"],
type="numpy",
streaming=False,
)
with gr.Row():
chatbot = gr.Chatbot(label="Conversation", type="messages")
state = gr.State(value=AppState())
stream = input_audio.start_recording(
process_audio,
[input_audio, state],
[input_audio, state],
)
respond = input_audio.stop_recording(
response, [state, input_audio], [state, chatbot]
)
restart = respond.then(start_recording_user, [state], [input_audio]).then(
lambda state: state, state, state, js=js_reset
)
cancel = gr.Button("Restart Conversation", variant="stop")
cancel.click(
lambda: (AppState(stopped=True), gr.Audio(recording=False)),
None,
[state, input_audio],
cancels=[respond, restart],
)
if __name__ == "__main__":
demo.launch()
|