Fix country/language selectors: Radio+flag-emoji values broke single-select (US never applied); use Dropdown with clean MX/US, en/es values
Browse files- app.py +8 -5
- modal_app/serve_llm_modal.py +9 -2
app.py
CHANGED
|
@@ -287,9 +287,12 @@ def build_demo() -> gr.Blocks:
|
|
| 287 |
# Holds only a session-id string (never the un-pickleable Ledger object).
|
| 288 |
session = gr.State(value=_new_session_id)
|
| 289 |
with gr.Row():
|
| 290 |
-
|
| 291 |
-
|
| 292 |
-
|
|
|
|
|
|
|
|
|
|
| 293 |
|
| 294 |
with gr.Tabs():
|
| 295 |
# ---- Capture ----
|
|
@@ -353,8 +356,8 @@ def build_demo() -> gr.Blocks:
|
|
| 353 |
with gr.Row():
|
| 354 |
a_year = gr.Dropdown(YEARS, value=2024, label="Year", scale=1)
|
| 355 |
a_month = gr.Dropdown(MONTHS, value=5, label="Month", scale=1)
|
| 356 |
-
a_lang = gr.
|
| 357 |
-
|
| 358 |
a_q = gr.Textbox(label="Your question",
|
| 359 |
placeholder="Which regime suits me? Can I deduct my laptop?")
|
| 360 |
a_go = gr.Button("Ask", variant="primary")
|
|
|
|
| 287 |
# Holds only a session-id string (never the un-pickleable Ledger object).
|
| 288 |
session = gr.State(value=_new_session_id)
|
| 289 |
with gr.Row():
|
| 290 |
+
# Use (label, value) tuples with PLAIN ascii values ("MX"/"US"). Flag-emoji
|
| 291 |
+
# values were breaking Gradio's option matching, so the selection never
|
| 292 |
+
# actually switched to USA. The emoji stays in the visible label only.
|
| 293 |
+
country = gr.Dropdown([("🇲🇽 Mexico", "MX"), ("🇺🇸 USA", "US")], value="MX",
|
| 294 |
+
label="Country / tax system", filterable=False,
|
| 295 |
+
info="Mexico: RESICO · IVA · SAT. USA: Schedule C · SE tax · federal.")
|
| 296 |
|
| 297 |
with gr.Tabs():
|
| 298 |
# ---- Capture ----
|
|
|
|
| 356 |
with gr.Row():
|
| 357 |
a_year = gr.Dropdown(YEARS, value=2024, label="Year", scale=1)
|
| 358 |
a_month = gr.Dropdown(MONTHS, value=5, label="Month", scale=1)
|
| 359 |
+
a_lang = gr.Dropdown([("English", "en"), ("Español", "es")], value="en",
|
| 360 |
+
label="Answer language", filterable=False, scale=1)
|
| 361 |
a_q = gr.Textbox(label="Your question",
|
| 362 |
placeholder="Which regime suits me? Can I deduct my laptop?")
|
| 363 |
a_go = gr.Button("Ask", variant="primary")
|
modal_app/serve_llm_modal.py
CHANGED
|
@@ -41,7 +41,11 @@ MINUTES = 60
|
|
| 41 |
@app.function(
|
| 42 |
image=vllm_image,
|
| 43 |
gpu="A10G",
|
| 44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
timeout=20 * MINUTES,
|
| 46 |
volumes={"/root/.cache/huggingface": hf_cache, "/root/.cache/vllm": vllm_cache},
|
| 47 |
secrets=[hf_secret],
|
|
@@ -57,8 +61,11 @@ def serve():
|
|
| 57 |
"--enable-auto-tool-choice",
|
| 58 |
"--tool-call-parser", "hermes",
|
| 59 |
"--reasoning-parser", "deepseek_r1", # handles Qwen3's <think> tags
|
| 60 |
-
"--max-model-len", "
|
| 61 |
"--gpu-memory-utilization", "0.92",
|
|
|
|
|
|
|
|
|
|
| 62 |
]
|
| 63 |
if MODEL_REVISION:
|
| 64 |
cmd += ["--revision", MODEL_REVISION]
|
|
|
|
| 41 |
@app.function(
|
| 42 |
image=vllm_image,
|
| 43 |
gpu="A10G",
|
| 44 |
+
# Keep one GPU warm during judging → no cold start, ~10-30s answers.
|
| 45 |
+
# ⚠️ COSTS ~$26/day in Modal credits. To stop the cost after judging, set
|
| 46 |
+
# min_containers=0 (or delete this line) and redeploy.
|
| 47 |
+
min_containers=1,
|
| 48 |
+
scaledown_window=10 * MINUTES,
|
| 49 |
timeout=20 * MINUTES,
|
| 50 |
volumes={"/root/.cache/huggingface": hf_cache, "/root/.cache/vllm": vllm_cache},
|
| 51 |
secrets=[hf_secret],
|
|
|
|
| 61 |
"--enable-auto-tool-choice",
|
| 62 |
"--tool-call-parser", "hermes",
|
| 63 |
"--reasoning-parser", "deepseek_r1", # handles Qwen3's <think> tags
|
| 64 |
+
"--max-model-len", "8192", # plenty for our prompts; faster KV alloc
|
| 65 |
"--gpu-memory-utilization", "0.92",
|
| 66 |
+
# Skip torch.compile + CUDA-graph capture — they added ~240s to cold start.
|
| 67 |
+
# Slightly slower per-token, but the model wakes up in ~1 min instead of ~5.
|
| 68 |
+
"--enforce-eager",
|
| 69 |
]
|
| 70 |
if MODEL_REVISION:
|
| 71 |
cmd += ["--revision", MODEL_REVISION]
|