yadongxie commited on
Commit
1926927
1 Parent(s): dec22aa

chore: update the layout

Browse files
.gradio/certificate.pem ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -----BEGIN CERTIFICATE-----
2
+ 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
31
+ -----END CERTIFICATE-----
.idea/.gitignore ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ # Default ignored files
2
+ /shelf/
3
+ /workspace.xml
4
+ # Editor-based HTTP Client requests
5
+ /httpRequests/
6
+ # Datasource local storage ignored files
7
+ /dataSources/
8
+ /dataSources.local.xml
.idea/inspectionProfiles/Project_Default.xml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <component name="InspectionProjectProfileManager">
2
+ <profile version="1.0">
3
+ <option name="myName" value="Project Default" />
4
+ <inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
5
+ <option name="ignoredPackages">
6
+ <value>
7
+ <list size="1">
8
+ <item index="0" class="java.lang.String" itemvalue="flash_attn" />
9
+ </list>
10
+ </value>
11
+ </option>
12
+ </inspection_tool>
13
+ </profile>
14
+ </component>
.idea/inspectionProfiles/profiles_settings.xml ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ <component name="InspectionProjectProfileManager">
2
+ <settings>
3
+ <option name="USE_PROJECT_PROFILE" value="false" />
4
+ <version value="1.0" />
5
+ </settings>
6
+ </component>
.idea/llama-3.2-3b-voice.iml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="PYTHON_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$">
5
+ <excludeFolder url="file://$MODULE_DIR$/venv" />
6
+ </content>
7
+ <orderEntry type="jdk" jdkName="Python 3.9" jdkType="Python SDK" />
8
+ <orderEntry type="sourceFolder" forTests="false" />
9
+ </component>
10
+ <component name="PyDocumentationSettings">
11
+ <option name="format" value="PLAIN" />
12
+ <option name="myDocStringFormat" value="Plain" />
13
+ </component>
14
+ </module>
.idea/misc.xml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="Black">
4
+ <option name="enabledOnSave" value="true" />
5
+ <option name="sdkName" value="Python 3.9" />
6
+ </component>
7
+ <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9" project-jdk-type="Python SDK" />
8
+ </project>
.idea/modules.xml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/llama-3.2-3b-voice.iml" filepath="$PROJECT_DIR$/.idea/llama-3.2-3b-voice.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="" vcs="Git" />
5
+ </component>
6
+ </project>
__pycache__/app.cpython-310.pyc ADDED
Binary file (6.18 kB). View file
 
app.py CHANGED
@@ -2,9 +2,7 @@ import gradio as gr
2
  import numpy as np
3
  import io
4
  from pydub import AudioSegment
5
- import tempfile
6
  import openai
7
- import time
8
  from dataclasses import dataclass, field
9
  from threading import Lock
10
  import base64
@@ -20,15 +18,17 @@ class AppState:
20
  output_format: str = "mp3"
21
  stopped: bool = False
22
 
 
23
  # Global lock for thread safety
24
  state_lock = Lock()
25
 
 
26
  def create_client(api_key):
27
  return openai.OpenAI(
28
- base_url="https://llama3-1-8b.lepton.run/api/v1/",
29
- api_key=api_key
30
  )
31
 
 
32
  def determine_pause(audio, sampling_rate, state):
33
  # Take the last 1 second of audio
34
  pause_length = int(sampling_rate * 1) # 1 second
@@ -45,6 +45,7 @@ def determine_pause(audio, sampling_rate, state):
45
  else:
46
  return False
47
 
 
48
  def process_audio(audio: tuple, state: AppState):
49
  if state.stream is None:
50
  state.stream = audio[1]
@@ -60,6 +61,7 @@ def process_audio(audio: tuple, state: AppState):
60
  else:
61
  return None, state
62
 
 
63
  def generate_response_and_audio(audio_bytes: bytes, state: AppState):
64
  if state.client is None:
65
  raise gr.Error("Please enter a valid API key first.")
@@ -74,10 +76,12 @@ def generate_response_and_audio(audio_bytes: bytes, state: AppState):
74
  "require_audio": True,
75
  "tts_preset_id": "jessica",
76
  "tts_audio_format": format_,
77
- "tts_audio_bitrate": bitrate
78
  },
79
  model="llama3.1-8b",
80
- messages=[{"role": "user", "content": [{"type": "audio", "data": audio_data}]}],
 
 
81
  temperature=0.7,
82
  max_tokens=256,
83
  stream=True,
@@ -90,20 +94,21 @@ def generate_response_and_audio(audio_bytes: bytes, state: AppState):
90
  if not chunk.choices:
91
  continue
92
  content = chunk.choices[0].delta.content
93
- audio = getattr(chunk.choices[0], 'audio', [])
94
  if content:
95
  full_response += content
96
  yield full_response, None, state
97
  if audio:
98
  audios.extend(audio)
99
 
100
- final_audio = b''.join([base64.b64decode(a) for a in audios])
101
 
102
  yield full_response, final_audio, state
103
 
104
  except Exception as e:
105
  raise gr.Error(f"Error during audio streaming: {e}")
106
 
 
107
  def response(state: AppState):
108
  if state.stream is None or len(state.stream) == 0:
109
  return None, None, state
@@ -139,43 +144,54 @@ def response(state: AppState):
139
 
140
  return chatbot_output, final_audio, state
141
 
 
142
  def start_recording_user(state: AppState):
143
  if not state.stopped:
144
  return gr.Audio(recording=True)
145
  else:
146
  return gr.Audio(recording=False)
147
 
 
148
  def set_api_key(api_key, state):
149
  if not api_key:
150
  raise gr.Error("Please enter a valid API key.")
151
- state.client = create_client(api_key)
152
- return "API key set successfully!", state
 
 
 
153
 
154
- def update_format(format, state):
155
- state.output_format = format
156
- return state
157
 
158
  with gr.Blocks() as demo:
 
 
 
 
159
  with gr.Row():
160
- api_key_input = gr.Textbox(type="password", label="Enter your Lepton API Key")
161
- set_key_button = gr.Button("Set API Key")
 
 
 
 
 
 
 
 
162
 
163
- api_key_status = gr.Textbox(label="API Key Status", interactive=False)
164
-
165
- with gr.Row():
166
- format_dropdown = gr.Dropdown(choices=["mp3", "opus"], value="mp3", label="Output Audio Format")
167
-
168
- with gr.Row():
169
- with gr.Column():
170
- input_audio = gr.Audio(label="Input Audio", sources="microphone", type="numpy")
171
- with gr.Column():
172
- chatbot = gr.Chatbot(label="Conversation", type="messages")
173
- output_audio = gr.Audio(label="Output Audio", autoplay=True)
174
 
175
  state = gr.State(AppState())
176
 
177
- set_key_button.click(set_api_key, inputs=[api_key_input, state], outputs=[api_key_status, state])
178
- format_dropdown.change(update_format, inputs=[format_dropdown, state], outputs=[state])
 
 
 
179
 
180
  stream = input_audio.stream(
181
  process_audio,
@@ -186,23 +202,20 @@ with gr.Blocks() as demo:
186
  )
187
 
188
  respond = input_audio.stop_recording(
189
- response,
190
- [state],
191
- [chatbot, output_audio, state]
192
  )
193
  # Update the chatbot with the final conversation
194
  respond.then(lambda s: s.conversation, [state], [chatbot])
195
 
196
  # Automatically restart recording after the assistant's response
197
- restart = output_audio.stop(
198
- start_recording_user,
199
- [state],
200
- [input_audio]
201
- )
202
 
203
  # Add a "Stop Conversation" button
204
- cancel = gr.Button("Stop Conversation", variant="stop")
205
- cancel.click(lambda: (AppState(stopped=True), gr.Audio(recording=False)), None,
206
- [state, input_audio], cancels=[respond, restart])
 
 
 
207
 
208
- demo.launch()
 
2
  import numpy as np
3
  import io
4
  from pydub import AudioSegment
 
5
  import openai
 
6
  from dataclasses import dataclass, field
7
  from threading import Lock
8
  import base64
 
18
  output_format: str = "mp3"
19
  stopped: bool = False
20
 
21
+
22
  # Global lock for thread safety
23
  state_lock = Lock()
24
 
25
+
26
  def create_client(api_key):
27
  return openai.OpenAI(
28
+ base_url="https://llama3-1-8b.lepton.run/api/v1/", api_key=api_key
 
29
  )
30
 
31
+
32
  def determine_pause(audio, sampling_rate, state):
33
  # Take the last 1 second of audio
34
  pause_length = int(sampling_rate * 1) # 1 second
 
45
  else:
46
  return False
47
 
48
+
49
  def process_audio(audio: tuple, state: AppState):
50
  if state.stream is None:
51
  state.stream = audio[1]
 
61
  else:
62
  return None, state
63
 
64
+
65
  def generate_response_and_audio(audio_bytes: bytes, state: AppState):
66
  if state.client is None:
67
  raise gr.Error("Please enter a valid API key first.")
 
76
  "require_audio": True,
77
  "tts_preset_id": "jessica",
78
  "tts_audio_format": format_,
79
+ "tts_audio_bitrate": bitrate,
80
  },
81
  model="llama3.1-8b",
82
+ messages=[
83
+ {"role": "user", "content": [{"type": "audio", "data": audio_data}]}
84
+ ],
85
  temperature=0.7,
86
  max_tokens=256,
87
  stream=True,
 
94
  if not chunk.choices:
95
  continue
96
  content = chunk.choices[0].delta.content
97
+ audio = getattr(chunk.choices[0], "audio", [])
98
  if content:
99
  full_response += content
100
  yield full_response, None, state
101
  if audio:
102
  audios.extend(audio)
103
 
104
+ final_audio = b"".join([base64.b64decode(a) for a in audios])
105
 
106
  yield full_response, final_audio, state
107
 
108
  except Exception as e:
109
  raise gr.Error(f"Error during audio streaming: {e}")
110
 
111
+
112
  def response(state: AppState):
113
  if state.stream is None or len(state.stream) == 0:
114
  return None, None, state
 
144
 
145
  return chatbot_output, final_audio, state
146
 
147
+
148
  def start_recording_user(state: AppState):
149
  if not state.stopped:
150
  return gr.Audio(recording=True)
151
  else:
152
  return gr.Audio(recording=False)
153
 
154
+
155
  def set_api_key(api_key, state):
156
  if not api_key:
157
  raise gr.Error("Please enter a valid API key.")
158
+ try:
159
+ state.client = create_client(api_key)
160
+ return gr.update(value="API key set successfully!", visible=True), state
161
+ except Exception as e:
162
+ return gr.update(value="Connection error", visible=True), state
163
 
 
 
 
164
 
165
  with gr.Blocks() as demo:
166
+ gr.Markdown("# Lepton LLM Voice Mode")
167
+ gr.Markdown(
168
+ "You can find Lepton serverless endpoint API Key at [here](https://dashboard.lepton.ai/workspace-redirect/settings/api-tokens)"
169
+ )
170
  with gr.Row():
171
+ with gr.Column(scale=3):
172
+ api_key_input = gr.Textbox(
173
+ type="password", label="Enter your Lepton API Key"
174
+ )
175
+ with gr.Column(scale=1):
176
+ set_key_button = gr.Button("Set API Key", scale=2, variant="secondary")
177
+
178
+ api_key_status = gr.Textbox(
179
+ show_label=False, container=False, interactive=False, visible=False
180
+ )
181
 
182
+ with gr.Blocks():
183
+ input_audio = gr.Audio(label="Input Audio", sources="microphone", type="numpy")
184
+ output_audio = gr.Audio(label="Output Audio", autoplay=True)
185
+ chatbot = gr.Chatbot(label="Conversation", type="messages")
186
+ cancel = gr.Button("Stop Conversation", variant="stop")
 
 
 
 
 
 
187
 
188
  state = gr.State(AppState())
189
 
190
+ set_key_button.click(
191
+ set_api_key,
192
+ inputs=[api_key_input, state],
193
+ outputs=[api_key_status, state],
194
+ )
195
 
196
  stream = input_audio.stream(
197
  process_audio,
 
202
  )
203
 
204
  respond = input_audio.stop_recording(
205
+ response, [state], [chatbot, output_audio, state]
 
 
206
  )
207
  # Update the chatbot with the final conversation
208
  respond.then(lambda s: s.conversation, [state], [chatbot])
209
 
210
  # Automatically restart recording after the assistant's response
211
+ restart = output_audio.stop(start_recording_user, [state], [input_audio])
 
 
 
 
212
 
213
  # Add a "Stop Conversation" button
214
+ cancel.click(
215
+ lambda: (AppState(stopped=True), gr.Audio(recording=False)),
216
+ None,
217
+ [state, input_audio],
218
+ cancels=[respond, restart],
219
+ )
220
 
221
+ demo.launch(share=True)