rogerkoranteng commited on
Commit
65f42dc
·
verified ·
1 Parent(s): 8df5a09

Upload folder using huggingface_hub

Browse files
Files changed (3) hide show
  1. README.md +2 -8
  2. main.py +348 -0
  3. requirements.txt +170 -0
README.md CHANGED
@@ -1,12 +1,6 @@
1
  ---
2
- title: Sage Mental Health Bot
3
- emoji: 🌍
4
- colorFrom: yellow
5
- colorTo: gray
6
  sdk: gradio
7
  sdk_version: 5.5.0
8
- app_file: app.py
9
- pinned: false
10
  ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: Sage-Mental-Health-Bot
3
+ app_file: main.py
 
 
4
  sdk: gradio
5
  sdk_version: 5.5.0
 
 
6
  ---
 
 
main.py ADDED
@@ -0,0 +1,348 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import json
4
+ from dotenv import load_dotenv
5
+ import requests
6
+ from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
7
+ from huggingface_hub import login
8
+ from datetime import datetime
9
+ import numpy as np
10
+ import torch
11
+ from gtts import gTTS
12
+ import tempfile
13
+ from transformers import Wav2Vec2ForCTC, Wav2Vec2Tokenizer
14
+ import torch
15
+
16
+ # Load environment variables from .env file
17
+ load_dotenv()
18
+ token = os.getenv("HF_TOKEN")
19
+
20
+ # Use the token in the login function
21
+ login(token=token)
22
+ # File paths for storing model configurations and chat history
23
+ MODEL_CONFIG_FILE = "model_config.json"
24
+ CHAT_HISTORY_FILE = "chat_history.json"
25
+
26
+ # Load model configurations from a JSON file (if exists)
27
+ def load_model_config():
28
+ if os.path.exists(MODEL_CONFIG_FILE):
29
+ with open(MODEL_CONFIG_FILE, 'r') as f:
30
+ return json.load(f)
31
+ return {
32
+ "gpt-4": {
33
+ "endpoint": "https://roger-m38jr9pd-eastus2.openai.azure.com/openai/deployments/gpt-4/chat/completions?api-version=2024-08-01-preview",
34
+ "api_key": os.getenv("GPT4_API_KEY"),
35
+ "model_path": None # No model path for API models
36
+ },
37
+ "gpt-4o": {
38
+ "endpoint": "https://roger-m38jr9pd-eastus2.openai.azure.com/openai/deployments/gpt-4o/chat/completions?api-version=2024-08-01-preview",
39
+ "api_key": os.getenv("GPT4O_API_KEY"),
40
+ "model_path": None
41
+ },
42
+ "gpt-35-turbo": {
43
+ "endpoint": "https://rogerkoranteng.openai.azure.com/openai/deployments/gpt-35-turbo/chat/completions?api-version=2024-08-01-preview",
44
+ "api_key": os.getenv("GPT35_TURBO_API_KEY"),
45
+ "model_path": None
46
+ },
47
+ "gpt-4-32k": {
48
+ "endpoint": "https://roger-m38orjxq-australiaeast.openai.azure.com/openai/deployments/gpt-4-32k/chat/completions?api-version=2024-08-01-preview",
49
+ "api_key": os.getenv("GPT4_32K_API_KEY"),
50
+ "model_path": None
51
+ }
52
+ }
53
+
54
+ predefined_messages = {
55
+ "feeling_sad": "Hello, I am feeling sad today, what should I do?",
56
+ "Nobody likes me": "Hello, Sage. I feel like nobody likes me. What should I do?",
57
+ 'Boyfriend broke up': "Hi Sage, my boyfriend broke up with me. I'm feeling so sad. What should I do?",
58
+ 'I am lonely': "Hi Sage, I am feeling lonely. What should I do?",
59
+ 'I am stressed': "Hi Sage, I am feeling stressed. What should I do?",
60
+ 'I am anxious': "Hi Sage, I am feeling anxious. What should I do?",
61
+ }
62
+
63
+ # Save model configuration to JSON
64
+ def save_model_config():
65
+ with open(MODEL_CONFIG_FILE, 'w') as f:
66
+ json.dump(model_config, f, indent=4)
67
+
68
+ # Load chat history from a JSON file
69
+ def load_chat_history():
70
+ if os.path.exists(CHAT_HISTORY_FILE):
71
+ with open(CHAT_HISTORY_FILE, 'r') as f:
72
+ return json.load(f)
73
+ return []
74
+
75
+ # Save chat history to a JSON file
76
+ def save_chat_history(chat_history):
77
+ with open(CHAT_HISTORY_FILE, 'w') as f:
78
+ json.dump(chat_history, f, indent=4)
79
+
80
+ # Define model configurations
81
+ model_config = load_model_config()
82
+
83
+ # Function to dynamically add downloaded model to model_config
84
+ def add_downloaded_model(model_name, model_path):
85
+ model_config[model_name] = {
86
+ "endpoint": None,
87
+ "model_path": model_path,
88
+ "api_key": None
89
+ }
90
+ save_model_config()
91
+ return list(model_config.keys())
92
+
93
+ # Function to download model from Hugging Face synchronously
94
+ def download_model(model_name):
95
+ try:
96
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
97
+ model = AutoModelForCausalLM.from_pretrained(model_name)
98
+ model_path = f"./models/{model_name}"
99
+ os.makedirs(model_path, exist_ok=True)
100
+ model.save_pretrained(model_path)
101
+ tokenizer.save_pretrained(model_path)
102
+ updated_models = add_downloaded_model(model_name, model_path)
103
+ return f"Model '{model_name}' downloaded and added.", updated_models
104
+ except Exception as e:
105
+ return f"Error downloading model '{model_name}': {e}", list(model_config.keys())
106
+
107
+ # Chat function using the selected model
108
+ def generate_response(model_choice, user_message, chat_history):
109
+ model_info = model_config.get(model_choice)
110
+ if not model_info:
111
+ return "Invalid model selection. Please choose a valid model.", chat_history
112
+
113
+ chat_history.append({"role": "user", "content": user_message})
114
+ headers = {"Content-Type": "application/json"}
115
+
116
+ # Check if the model is an API model (it will have an endpoint)
117
+ if model_info["endpoint"]:
118
+ if model_info["api_key"]:
119
+ headers["api-key"] = model_info["api_key"]
120
+
121
+ data = {"messages": chat_history, "max_tokens": 1500, "temperature": 0.7}
122
+
123
+ try:
124
+ # Send request to the API model endpoint
125
+ response = requests.post(model_info["endpoint"], headers=headers, json=data)
126
+ response.raise_for_status()
127
+ assistant_message = response.json()['choices'][0]['message']['content']
128
+ chat_history.append({"role": "assistant", "content": assistant_message})
129
+ save_chat_history(chat_history) # Save chat history to JSON
130
+ except requests.exceptions.RequestException as e:
131
+ assistant_message = f"Error: {e}"
132
+ chat_history.append({"role": "assistant", "content": assistant_message})
133
+ save_chat_history(chat_history)
134
+ else:
135
+ # If it's a local model, load the model and tokenizer from the local path
136
+ model_path = model_info["model_path"]
137
+ try:
138
+ tokenizer = AutoTokenizer.from_pretrained(model_path)
139
+ model = AutoModelForCausalLM.from_pretrained(model_path)
140
+
141
+ inputs = tokenizer(user_message, return_tensors="pt")
142
+ outputs = model.generate(inputs['input_ids'], max_length=500, num_return_sequences=1)
143
+ assistant_message = tokenizer.decode(outputs[0], skip_special_tokens=True)
144
+
145
+ chat_history.append({"role": "assistant", "content": assistant_message})
146
+ save_chat_history(chat_history)
147
+ except Exception as e:
148
+ assistant_message = f"Error loading model locally: {e}"
149
+ chat_history.append({"role": "assistant", "content": assistant_message})
150
+ save_chat_history(chat_history)
151
+
152
+ # Convert the assistant message to audio
153
+ tts = gTTS(assistant_message)
154
+ audio_file = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3")
155
+ tts.save(audio_file.name)
156
+
157
+ return chat_history, audio_file.name
158
+
159
+ # Function to format chat history with custom bubble styles
160
+ def format_chat_bubble(history):
161
+ formatted_history = ""
162
+ for message in history:
163
+ timestamp = datetime.now().strftime("%H:%M:%S")
164
+ if message["role"] == "user":
165
+ formatted_history += f'''
166
+ <div class="user-bubble">
167
+ <strong>Me:</strong> {message["content"]}
168
+ </div>
169
+ '''
170
+ else:
171
+ formatted_history += f'''
172
+ <div class="assistant-bubble">
173
+ <strong>Sage:</strong> {message["content"]}
174
+ </div>
175
+ '''
176
+ return formatted_history
177
+
178
+ tokenizer = Wav2Vec2Tokenizer.from_pretrained("facebook/wav2vec2-base-960h")
179
+ model = Wav2Vec2ForCTC.from_pretrained("facebook/wav2vec2-base-960h")
180
+
181
+ def transcribe(audio):
182
+ if audio is None:
183
+ return "No audio input received."
184
+
185
+ sr, y = audio
186
+
187
+ # Convert to mono if stereo
188
+ if y.ndim > 1:
189
+ y = y.mean(axis=1)
190
+
191
+ y = y.astype(np.float32)
192
+ y /= np.max(np.abs(y))
193
+
194
+ # Tokenize the audio
195
+ input_values = tokenizer(y, return_tensors="pt", sampling_rate=sr).input_values
196
+
197
+ # Perform inference
198
+ with torch.no_grad():
199
+ logits = model(input_values).logits
200
+
201
+ # Decode the logits
202
+ predicted_ids = torch.argmax(logits, dim=-1)
203
+ transcription = tokenizer.decode(predicted_ids[0])
204
+
205
+ return transcription
206
+
207
+ # Create the Gradio interface
208
+ with gr.Blocks() as interface:
209
+ gr.Markdown("## Chat with Sage - Your Mental Health Advisor")
210
+
211
+ with gr.Tab("Model Management"):
212
+ with gr.Tabs():
213
+ with gr.TabItem("Model Selection"):
214
+ gr.Markdown("### Select Model for Chat")
215
+ model_dropdown = gr.Dropdown(choices=list(model_config.keys()), label="Choose a Model", value="gpt-4",
216
+ allow_custom_value=True)
217
+ status_textbox = gr.Textbox(label="Model Selection Status", value="Selected model: gpt-4")
218
+ model_dropdown.change(lambda model: f"Selected model: {model}", inputs=model_dropdown,
219
+ outputs=status_textbox)
220
+
221
+ with gr.TabItem("Download Model"): # Sub-tab for downloading models
222
+ gr.Markdown("### Download a Model from Hugging Face")
223
+ model_name_input = gr.Textbox(label="Enter Model Name from Hugging Face (e.g., gpt2)")
224
+ download_button = gr.Button("Download Model")
225
+ download_status = gr.Textbox(label="Download Status")
226
+
227
+ # Model download synchronous handler
228
+ def on_model_download(model_name):
229
+ download_message, updated_models = download_model(model_name)
230
+ # Trigger the dropdown update to show the newly added model
231
+ return download_message, gr.update(choices=updated_models, value=updated_models[-1])
232
+
233
+ download_button.click(on_model_download, inputs=model_name_input,
234
+ outputs=[download_status, model_dropdown])
235
+
236
+ refresh_button = gr.Button("Refresh Model List")
237
+ refresh_button.click(lambda: gr.update(choices=list(model_config.keys())), inputs=[],
238
+ outputs=model_dropdown)
239
+
240
+ with gr.Tab("Chat Interface"):
241
+ gr.Markdown("### Chat with Sage")
242
+
243
+ # Chat history state for tracking conversation
244
+ chat_history_state = gr.State(load_chat_history()) # Load existing chat history
245
+
246
+ # Add initial introduction message
247
+ if not chat_history_state.value:
248
+ chat_history_state.value.append({"role": "assistant", "content": "Hello, I am Sage. How can I assist you today?"})
249
+
250
+ chat_display = gr.HTML(label="Chat", value=format_chat_bubble(chat_history_state.value), elem_id="chat-display")
251
+
252
+ user_message = gr.Textbox(placeholder="Type your message here...", label="Your Message")
253
+ send_button = gr.Button("Send Message")
254
+
255
+ # Predefined message buttons
256
+ predefined_buttons = [gr.Button(value=msg) for msg in predefined_messages.values()]
257
+
258
+ # Real-time message updating
259
+ def update_chat(model_choice, user_message, chat_history_state):
260
+ chat_history, audio_file = generate_response(model_choice, user_message, chat_history_state)
261
+ formatted_chat = format_chat_bubble(chat_history)
262
+ return formatted_chat, chat_history, audio_file
263
+
264
+ send_button.click(
265
+ update_chat,
266
+ inputs=[model_dropdown, user_message, chat_history_state],
267
+ outputs=[chat_display, chat_history_state, gr.Audio(autoplay=True)]
268
+ )
269
+
270
+ send_button.click(lambda: "", None, user_message) # Clears the user input after sending
271
+
272
+ # Add click events for predefined message buttons
273
+ for button, message in zip(predefined_buttons, predefined_messages.values()):
274
+ button.click(
275
+ update_chat,
276
+ inputs=[model_dropdown, gr.State(message), chat_history_state],
277
+ outputs=[chat_display, chat_history_state, gr.Audio(autoplay=True)]
278
+ )
279
+
280
+ with gr.Tab("Speech Interface"):
281
+ gr.Markdown("### Speak with Sage")
282
+
283
+ audio_input = gr.Audio(type="numpy")
284
+ transcribe_button = gr.Button("Transcribe")
285
+ transcribed_text = gr.Textbox(label="Transcribed Text")
286
+
287
+ transcribe_button.click(
288
+ transcribe,
289
+ inputs=audio_input,
290
+ outputs=transcribed_text
291
+ )
292
+
293
+ send_speech_button = gr.Button("Send Speech Message")
294
+
295
+ send_speech_button.click(
296
+ update_chat,
297
+ inputs=[model_dropdown, transcribed_text, chat_history_state],
298
+ outputs=[chat_display, chat_history_state, gr.Audio(autoplay=True)]
299
+ )
300
+
301
+ # Add custom CSS for scrolling chat box and bubbles
302
+ interface.css = """
303
+ #chat-display {
304
+ max-height: 500px;
305
+ overflow-y: auto;
306
+ padding: 10px;
307
+ background-color: #1a1a1a;
308
+ border-radius: 10px;
309
+ display: flex;
310
+ flex-direction: column;
311
+ justify-content: flex-start;
312
+ box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
313
+ scroll-behavior: smooth;
314
+ }
315
+
316
+ /* User message style - text only */
317
+ .user-bubble {
318
+ color: #ffffff; /* Text color for the user */
319
+ padding: 8px 15px;
320
+ margin: 8px 0;
321
+ word-wrap: break-word;
322
+ align-self: flex-end;
323
+ font-size: 14px;
324
+ position: relative;
325
+ max-width: 70%; /* Make the bubble width dynamic */
326
+ border-radius: 15px;
327
+ background-color: #121212; /* Light cyan background for the user */
328
+ transition: color 0.3s ease;
329
+ }
330
+
331
+ /* Assistant message style - text only */
332
+ .assistant-bubble {
333
+ color: #ffffff; /* Text color for the assistant */
334
+ padding: 8px 15px;
335
+ margin: 8px 0;
336
+ word-wrap: break-word;
337
+ align-self: flex-start;
338
+ background-color: #2a2a2a;
339
+ font-size: 14px;
340
+ position: relative;
341
+ max-width: 70%;
342
+ transition: color 0.3s ease;
343
+ }
344
+
345
+ """
346
+
347
+ # Launch the Gradio interface
348
+ interface.launch(server_name="0.0.0.0", server_port=8080, share=True)
requirements.txt ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ aiofiles==23.2.1
2
+ aiohappyeyeballs==2.4.3
3
+ aiohttp==3.10.10
4
+ aiosignal==1.3.1
5
+ analytics-python==1.4.post1
6
+ annotated-types==0.7.0
7
+ anyio==3.7.1
8
+ asgiref==3.8.1
9
+ async-timeout==4.0.3
10
+ attrs==24.2.0
11
+ backoff==1.10.0
12
+ bcrypt==4.2.0
13
+ build==1.2.2.post1
14
+ cachetools==5.5.0
15
+ certifi==2024.8.30
16
+ cffi==1.17.1
17
+ charset-normalizer==3.4.0
18
+ chroma-bullet==2.2.0
19
+ chroma-hnswlib==0.7.6
20
+ chroma-migrate==0.0.7
21
+ chromadb==0.5.18
22
+ click==8.1.7
23
+ clickhouse-connect==0.6.6
24
+ coloredlogs==15.0.1
25
+ contourpy==1.3.0
26
+ cryptography==43.0.3
27
+ cycler==0.12.1
28
+ Deprecated==1.2.14
29
+ duckdb==0.7.1
30
+ durationpy==0.9
31
+ exceptiongroup==1.2.2
32
+ fastapi==0.115.4
33
+ ffmpeg==1.4
34
+ ffmpy==0.4.0
35
+ filelock==3.16.1
36
+ flatbuffers==24.3.25
37
+ fonttools==4.54.1
38
+ frozenlist==1.5.0
39
+ fsspec==2024.10.0
40
+ google-auth==2.36.0
41
+ googleapis-common-protos==1.65.0
42
+ gradio==5.5.0
43
+ gradio_client==1.4.2
44
+ grpcio==1.67.1
45
+ gTTS==2.5.4
46
+ h11==0.14.0
47
+ HLL==2.2.0
48
+ httpcore==1.0.6
49
+ httptools==0.6.4
50
+ httpx==0.27.2
51
+ huggingface-hub==0.26.2
52
+ humanfriendly==10.0
53
+ idna==3.10
54
+ importlib_metadata==8.5.0
55
+ importlib_resources==6.4.5
56
+ Jinja2==3.1.4
57
+ joblib==1.4.2
58
+ kiwisolver==1.4.7
59
+ kubernetes==31.0.0
60
+ linkify-it-py==2.0.3
61
+ lz4==4.3.3
62
+ markdown-it-py==3.0.0
63
+ MarkupSafe==2.1.5
64
+ matplotlib==3.9.2
65
+ mdit-py-plugins==0.4.2
66
+ mdurl==0.1.2
67
+ mmh3==5.0.1
68
+ monotonic==1.6
69
+ more-itertools==10.5.0
70
+ mpmath==1.3.0
71
+ multidict==6.1.0
72
+ networkx==3.4.2
73
+ nltk==3.9.1
74
+ numpy==1.23.5
75
+ nvidia-cublas-cu12==12.1.3.1
76
+ nvidia-cuda-cupti-cu12==12.1.105
77
+ nvidia-cuda-nvrtc-cu12==12.1.105
78
+ nvidia-cuda-runtime-cu12==12.1.105
79
+ nvidia-cudnn-cu12==9.1.0.70
80
+ nvidia-cufft-cu12==11.0.2.54
81
+ nvidia-curand-cu12==10.3.2.106
82
+ nvidia-cusolver-cu12==11.4.5.107
83
+ nvidia-cusparse-cu12==12.1.0.106
84
+ nvidia-cusparselt-cu12==0.6.2
85
+ nvidia-nccl-cu12==2.21.5
86
+ nvidia-nvjitlink-cu12==12.4.127
87
+ nvidia-nvtx-cu12==12.1.105
88
+ oauthlib==3.2.2
89
+ onnxruntime==1.20.0
90
+ opentelemetry-api==1.28.1
91
+ opentelemetry-exporter-otlp-proto-common==1.28.1
92
+ opentelemetry-exporter-otlp-proto-grpc==1.28.1
93
+ opentelemetry-instrumentation==0.49b1
94
+ opentelemetry-instrumentation-asgi==0.49b1
95
+ opentelemetry-instrumentation-fastapi==0.49b1
96
+ opentelemetry-proto==1.28.1
97
+ opentelemetry-sdk==1.28.1
98
+ opentelemetry-semantic-conventions==0.49b1
99
+ opentelemetry-util-http==0.49b1
100
+ orjson==3.10.11
101
+ overrides==7.7.0
102
+ packaging==24.2
103
+ pandas==1.5.3
104
+ paramiko==3.5.0
105
+ pillow==11.0.0
106
+ plotly==5.14.0
107
+ posthog==3.7.0
108
+ propcache==0.2.0
109
+ protobuf==5.28.3
110
+ pulsar-client==3.5.0
111
+ pyasn1==0.6.1
112
+ pyasn1_modules==0.4.1
113
+ pycparser==2.22
114
+ pycryptodome==3.21.0
115
+ pydantic==2.9.2
116
+ pydantic_core==2.23.4
117
+ pydub==0.25.1
118
+ Pygments==2.18.0
119
+ PyNaCl==1.5.0
120
+ pyparsing==3.2.0
121
+ PyPika==0.48.9
122
+ pyproject_hooks==1.2.0
123
+ python-dateutil==2.9.0.post0
124
+ python-dotenv==1.0.1
125
+ python-multipart==0.0.12
126
+ pytorch-triton==3.1.0+cf34004b8a
127
+ pytz==2024.2
128
+ PyYAML==6.0.2
129
+ regex==2024.11.6
130
+ requests==2.32.3
131
+ requests-oauthlib==2.0.0
132
+ rich==13.9.4
133
+ rsa==4.9
134
+ ruff==0.7.3
135
+ safehttpx==0.1.1
136
+ safetensors==0.4.5
137
+ scikit-learn==1.1.3
138
+ scipy==1.14.1
139
+ semantic-version==2.10.0
140
+ sentence-transformers==3.2.1
141
+ sentencepiece==0.2.0
142
+ shellingham==1.5.4
143
+ six==1.16.0
144
+ sniffio==1.3.1
145
+ starlette==0.41.2
146
+ sympy==1.13.1
147
+ tenacity==9.0.0
148
+ threadpoolctl==3.5.0
149
+ tokenizers==0.20.3
150
+ tomli==2.0.2
151
+ tomlkit==0.12.0
152
+ torch==2.6.0.dev20241107+cu121
153
+ torchaudio==2.5.0.dev20241107+cu121
154
+ torchvision==0.20.0.dev20241107+cu121
155
+ tqdm==4.67.0
156
+ transformers==4.46.2
157
+ triton==3.1.0
158
+ typer==0.13.0
159
+ typing_extensions==4.12.2
160
+ uc-micro-py==1.0.3
161
+ urllib3==2.2.3
162
+ uvicorn==0.32.0
163
+ uvloop==0.21.0
164
+ watchfiles==0.24.0
165
+ websocket-client==1.8.0
166
+ websockets==12.0
167
+ wrapt==1.16.0
168
+ yarl==1.17.1
169
+ zipp==3.20.2
170
+ zstandard==0.23.0