Fix: Enabled live charting with throttled rendering and restored API key visibility in a persistent Accordion
Browse files- app.py +28 -37
- inference/vllm_client.py +1 -0
app.py
CHANGED
|
@@ -308,6 +308,9 @@ def run_simulation(n_mom, n_mr, n_fund, n_noise, n_mm,
|
|
| 308 |
"""Run the full simulation and return all visualization components."""
|
| 309 |
print(f"DEBUG: Starting simulation - LLM: {use_llm}, URL: {vllm_url}")
|
| 310 |
|
|
|
|
|
|
|
|
|
|
| 311 |
agents = build_agents(int(n_mom), int(n_mr), int(n_fund), int(n_noise), int(n_mm))
|
| 312 |
if not agents:
|
| 313 |
raise gr.Error("Add at least one agent to run the simulation.")
|
|
@@ -318,6 +321,7 @@ def run_simulation(n_mom, n_mr, n_fund, n_noise, n_mm,
|
|
| 318 |
use_llm=use_llm,
|
| 319 |
vllm_base_url=vllm_url if vllm_url else "https://api-inference.huggingface.co/v1",
|
| 320 |
vllm_model=hf_model if hf_model else "Qwen/Qwen2.5-7B-Instruct",
|
|
|
|
| 321 |
log_to_csv=False,
|
| 322 |
base_volatility=volatility,
|
| 323 |
warmup_ticks=int(warmup_ticks),
|
|
@@ -327,13 +331,6 @@ def run_simulation(n_mom, n_mr, n_fund, n_noise, n_mm,
|
|
| 327 |
|
| 328 |
engine = SimulationEngine(agents, config)
|
| 329 |
|
| 330 |
-
if use_llm and api_key and engine.llm_client:
|
| 331 |
-
import openai
|
| 332 |
-
engine.llm_client.client = openai.AsyncOpenAI(
|
| 333 |
-
base_url=config.vllm_base_url,
|
| 334 |
-
api_key=api_key,
|
| 335 |
-
)
|
| 336 |
-
|
| 337 |
try:
|
| 338 |
t0 = time.time()
|
| 339 |
|
|
@@ -343,25 +340,25 @@ def run_simulation(n_mom, n_mr, n_fund, n_noise, n_mm,
|
|
| 343 |
# Generator for real-time updates
|
| 344 |
print("DEBUG: Executing simulation loop...")
|
| 345 |
for tick in engine.run_generator():
|
| 346 |
-
#
|
| 347 |
-
if
|
| 348 |
-
|
| 349 |
-
|
| 350 |
-
|
| 351 |
-
|
| 352 |
-
|
| 353 |
-
|
| 354 |
-
|
| 355 |
-
|
| 356 |
-
|
| 357 |
-
|
| 358 |
-
|
| 359 |
-
|
| 360 |
-
|
| 361 |
-
|
| 362 |
-
stats_html = build_stats_html(ticks_data, pnl_data, time.time() - t0)
|
| 363 |
|
| 364 |
-
|
|
|
|
| 365 |
|
| 366 |
print(f"DEBUG: Simulation complete in {time.time()-t0:.2f}s")
|
| 367 |
|
|
@@ -551,30 +548,24 @@ def create_app():
|
|
| 551 |
use_llm = gr.Checkbox(label="Live LLM Mode", value=False,
|
| 552 |
info="Check this to use external API for live inference")
|
| 553 |
|
| 554 |
-
with gr.Accordion("Live LLM Settings
|
| 555 |
engine_preset = gr.Radio(
|
| 556 |
["AMD Cloud (vLLM)", "Groq (Demo Mode)"],
|
| 557 |
label="Infrastructure Preset",
|
| 558 |
value="AMD Cloud (vLLM)"
|
| 559 |
)
|
| 560 |
api_key = gr.Textbox(label="API Key", type="password",
|
| 561 |
-
placeholder="hf_... or gsk_...")
|
| 562 |
-
hf_model = gr.Textbox(label="Model ID", value="Qwen/Qwen2.5-7B-Instruct")
|
| 563 |
vllm_url = gr.Textbox(label="Inference Base URL",
|
| 564 |
value="https://api-inference.huggingface.co/v1",
|
| 565 |
-
placeholder="http://YOUR_AMD_IP:8000/v1")
|
| 566 |
|
| 567 |
def update_preset(preset):
|
| 568 |
if preset == "Groq (Demo Mode)":
|
| 569 |
-
return
|
| 570 |
-
gr.update(value="llama-3.1-8b-instant"),
|
| 571 |
-
gr.update(value="https://api.groq.com/openai/v1")
|
| 572 |
-
)
|
| 573 |
else:
|
| 574 |
-
return
|
| 575 |
-
gr.update(value="Qwen/Qwen2.5-7B-Instruct"),
|
| 576 |
-
gr.update(value="https://api-inference.huggingface.co/v1")
|
| 577 |
-
)
|
| 578 |
|
| 579 |
engine_preset.change(
|
| 580 |
fn=update_preset,
|
|
|
|
| 308 |
"""Run the full simulation and return all visualization components."""
|
| 309 |
print(f"DEBUG: Starting simulation - LLM: {use_llm}, URL: {vllm_url}")
|
| 310 |
|
| 311 |
+
if use_llm and not api_key.strip():
|
| 312 |
+
raise gr.Error("API Key is required when Live LLM Mode is enabled. Please expand 'Live LLM Settings' and provide your key.")
|
| 313 |
+
|
| 314 |
agents = build_agents(int(n_mom), int(n_mr), int(n_fund), int(n_noise), int(n_mm))
|
| 315 |
if not agents:
|
| 316 |
raise gr.Error("Add at least one agent to run the simulation.")
|
|
|
|
| 321 |
use_llm=use_llm,
|
| 322 |
vllm_base_url=vllm_url if vllm_url else "https://api-inference.huggingface.co/v1",
|
| 323 |
vllm_model=hf_model if hf_model else "Qwen/Qwen2.5-7B-Instruct",
|
| 324 |
+
vllm_api_key=api_key if api_key else "EMPTY",
|
| 325 |
log_to_csv=False,
|
| 326 |
base_volatility=volatility,
|
| 327 |
warmup_ticks=int(warmup_ticks),
|
|
|
|
| 331 |
|
| 332 |
engine = SimulationEngine(agents, config)
|
| 333 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 334 |
try:
|
| 335 |
t0 = time.time()
|
| 336 |
|
|
|
|
| 340 |
# Generator for real-time updates
|
| 341 |
print("DEBUG: Executing simulation loop...")
|
| 342 |
for tick in engine.run_generator():
|
| 343 |
+
# Throttled UI updates (every 2 ticks) for smoother animation and better browser performance
|
| 344 |
+
if tick % 2 == 0 or tick == int(num_ticks):
|
| 345 |
+
# Progress update
|
| 346 |
+
desc = f"Simulating market dynamics... {tick}/{num_ticks}"
|
| 347 |
+
|
| 348 |
+
# Build current results for real-time display
|
| 349 |
+
ticks_data = engine.csv_rows
|
| 350 |
+
pnl_data = engine.agent_pnl_rows
|
| 351 |
+
|
| 352 |
+
if ticks_data:
|
| 353 |
+
main_chart = build_main_chart(ticks_data)
|
| 354 |
+
pnl_chart = build_pnl_chart(pnl_data, agents)
|
| 355 |
+
leaderboard = build_leaderboard(pnl_data, ticks_data)
|
| 356 |
+
stats_html = build_stats_html(ticks_data, pnl_data, time.time() - t0)
|
| 357 |
+
|
| 358 |
+
yield main_chart, pnl_chart, leaderboard, stats_html, None
|
|
|
|
| 359 |
|
| 360 |
+
# Small sleep to allow Gradio's websocket to flush the update
|
| 361 |
+
time.sleep(0.01)
|
| 362 |
|
| 363 |
print(f"DEBUG: Simulation complete in {time.time()-t0:.2f}s")
|
| 364 |
|
|
|
|
| 548 |
use_llm = gr.Checkbox(label="Live LLM Mode", value=False,
|
| 549 |
info="Check this to use external API for live inference")
|
| 550 |
|
| 551 |
+
with gr.Accordion("🔑 Live LLM Settings", open=True) as llm_settings:
|
| 552 |
engine_preset = gr.Radio(
|
| 553 |
["AMD Cloud (vLLM)", "Groq (Demo Mode)"],
|
| 554 |
label="Infrastructure Preset",
|
| 555 |
value="AMD Cloud (vLLM)"
|
| 556 |
)
|
| 557 |
api_key = gr.Textbox(label="API Key", type="password",
|
| 558 |
+
placeholder="hf_... or gsk_...", interactive=True)
|
| 559 |
+
hf_model = gr.Textbox(label="Model ID", value="Qwen/Qwen2.5-7B-Instruct", interactive=True)
|
| 560 |
vllm_url = gr.Textbox(label="Inference Base URL",
|
| 561 |
value="https://api-inference.huggingface.co/v1",
|
| 562 |
+
placeholder="http://YOUR_AMD_IP:8000/v1", interactive=True)
|
| 563 |
|
| 564 |
def update_preset(preset):
|
| 565 |
if preset == "Groq (Demo Mode)":
|
| 566 |
+
return "llama-3.1-8b-instant", "https://api.groq.com/openai/v1"
|
|
|
|
|
|
|
|
|
|
| 567 |
else:
|
| 568 |
+
return "Qwen/Qwen2.5-7B-Instruct", "https://api-inference.huggingface.co/v1"
|
|
|
|
|
|
|
|
|
|
| 569 |
|
| 570 |
engine_preset.change(
|
| 571 |
fn=update_preset,
|
inference/vllm_client.py
CHANGED
|
@@ -168,6 +168,7 @@ class VLLMClient:
|
|
| 168 |
|
| 169 |
except Exception as e:
|
| 170 |
latency_ms = (time.perf_counter() - t0) * 1000
|
|
|
|
| 171 |
return LLMResponse(
|
| 172 |
action="hold", price=0.0, quantity=0,
|
| 173 |
raw_text=f"ERROR: {e}", latency_ms=latency_ms, success=False,
|
|
|
|
| 168 |
|
| 169 |
except Exception as e:
|
| 170 |
latency_ms = (time.perf_counter() - t0) * 1000
|
| 171 |
+
print(f"LLM API Error for {self.model}: {e}")
|
| 172 |
return LLMResponse(
|
| 173 |
action="hold", price=0.0, quantity=0,
|
| 174 |
raw_text=f"ERROR: {e}", latency_ms=latency_ms, success=False,
|