third-eye / FIXES_REPORT.md
mitvho09's picture
Upload folder using huggingface_hub
031e3f9 verified
|
Raw
History Blame Contribute Delete
7.44 kB

A newer version of the Gradio SDK is available: 6.19.0

Upgrade

Third Eye β€” Fixes Report (root causes + verification)

TL;DR

  • STT was NOT inherently slow. The Cohere card advertises RTFx 500 ("blazing fast"). The ~5-minute transcriptions were a configuration bug: float32 + device_map="auto" ran the model on CPU / partially offloaded (1s per forward pass). Keep Cohere β€” it wins the Cohere prize. Do NOT switch to Whisper.
  • Vision hallucinations ($20 for $18) came from sampling; switched to greedy + bf16.
  • All other reported bugs were already fixed; verified in code. 3 minor issues closed.
  • 38/38 unit tests pass (CPU). GPU fixes MEASURED on Modal A10G: STT 5 min β†’ 0.6s warm; vision now reads $18 (not $20) and mango lassi (not MANGOLAISSI). See "Verification" below.

Root cause analysis

BUG 1 β€” STT slow (~5 min). FIXED (config) β€” cohere_stt.py

Evidence: logs show 1.01s/it per forward pass. A 2B model on an A10G does a forward pass in ~10–30 ms, not ~1000 ms. The model card benchmarks RTFx ~524 (a 6 s clip β‰ˆ 0.01 s of compute). The app was ~25,000Γ— slower than the model's own benchmark β†’ not the model, the config.

Three compounding causes, all fixed:

  1. from_pretrained(..., device_map="auto") with no torch_dtype β†’ loaded in float32. On a single-GPU container this both doubles memory and pushes layers toward CPU offload, which streams weights per token. β†’ Now: torch_dtype=bfloat16 and an explicit .to("cuda").
  2. No decoding flags β†’ if generation_config defaulted to beam search, every token costs N forward passes (the repeated 6/6 progress bars). β†’ Now: num_beams=1, do_sample=False (greedy).
  3. max_new_tokens=256 β†’ trimmed to 128 (speech answers are short).

Why this is the fix and not a guess: greedy + half-precision + single-GPU pin is the standard cure for "transformers generate is mysteriously 100Γ—+ too slow," and it directly removes every mechanism the logs pointed at (per-forward CPU cost, per-token beam multiplier).

BUG 1b β€” "Ask" mode answered the wrong question. FIXED β€” cohere_stt.py

Symptom: spoken questions weren't answered correctly. Not a wiring bug β€” the vision model answers fine. The STT was hallucinating a tail over trailing silence:

SPOKEN: 'What is the cheapest item on the menu and how much does it cost?'
HEARD:  'What is the cheapest item on the menu and how much does it cost? Yes, sir. It was a clue.'  ← fake

The fake tail corrupts the question handed to the vision model (here it survived because the real text came first; with a shorter/noisier real-mic clip the tail dominates and the answer goes wrong). Fix: trim leading/trailing silence with librosa.effects.trim(top_db=30) before transcription β€” removes the silent padding the model hallucinates over. Verified:

HEARD: 'What is the cheapest item on the menu and how much does it cost?'   (exact match, 39->29 tokens)
HEARD: 'How often should I take this medication?' -> ANSWER: 'take one capsule every 8 hours.'  (correct)
clean-clip regression: 'Hello, this is a test...' still transcribes perfectly.

Vision hallucination ($20β‰ $18). FIXED β€” modal_backend.py

sampling=True, temperature=0.2 still lets the model invent plausible-but-wrong numbers. Switched to sampling=False (greedy) β€” the faithful, repeatable choice for an accessibility/OCR tool β€” and bf16 (what the MiniCPM-V-2 card recommends; more stable than fp16 on small text).

Temp-file leak. FIXED β€” utils.py + app.py

bytes_to_wav() left WAVs in temp forever. Added prune_old_wavs() (removes only Third-Eye WAVs older than 10 min, so a clip still being served is never deleted), called at each pipeline start.

Previously-reported bugs β€” verified fixed in code

  • READ "s" output β†’ improved verbatim prompt (app.py: resolve_question). βœ“
  • repetition_penalty/max_new_tokens removed from model.chat (they caused refusals). βœ“
  • STT gated-model 403 β†’ specific, actionable error message. βœ“
  • safe_call now surfaces exception type+message (truncated). βœ“

Read Text OCR distortion (MANGOLAISSI). FIXED (mitigated) β€” modal_backend.py

Root cause: small text on a full 1024x1536 image exceeds a 2.8B VLM's effective OCR resolution, so it merged MANGO LASSI -> MANGOLAISSI. Prompt engineering did NOT help (tested: still MANGOLIASSI + a hallucinated price). Validated cause: cropping to the text region fixed it (Mango Lassi $5), proving it's a resolution problem, not a knowledge problem.

Fix: automatic tiled OCR for Read Text mode (describe_scene(..., tile=True)): split the image into two overlapping top/bottom bands, OCR each (enlarges relative text), and stitch the results with word-overlap dedup (stitch_overlapping_text, unit-tested). Automatic β€” no box-drawing, which matters because the user is blind and can't draw a selection box. Measured:

label:  AMOXICILLIN 500 mg Take one capsule every 8 hours Finish all medication EXP 12/2027   (perfect)
sign:   CENTRAL STATION 250 m PLATFORM 1-6                                                     (perfect)
menu:   ...GRILLED FISH $18 MANGOS LASSI $5    (space restored & readable; was "MANGOLAISSI")

Residual honest limit: the menu still shows a minor glyph error (MANGOS), the genuine 2.8B ceiling. It is now legible speech, not gibberish. Cost: Read Text does 2 model calls (~6s).

Faster-model question

Within Cohere's family this transcribe model is the ASR model, and once configured correctly it is fast (RTFx ~500). No turbo variant is needed. Keeping Cohere keeps the Cohere award eligible.


Verification β€” MEASURED on Modal GPU (A10G), 2026-06-14

Local (CPU, this machine):

  • 38/38 unit tests pass (python -m pytest -q); ruff check clean; both modules import.

STT benchmark (modal run modal_backend.py::stt_benchmark):

[third-eye STT] loaded CohereLabs/cohere-transcribe-03-2026 | cuda_available=True | device=cuda:0 | dtype=torch.bfloat16
[COLD] total round-trip: 58.8s          (one-time container + model load)
[third-eye STT] generate: 1.56s for 26 tokens   (first call, includes CUDA warmup)
[third-eye STT] generate: 0.16s for 26 tokens   (warm: ~160 tok/s β€” correct for 2B on A10G)
[WARM] total round-trip: 0.6s
transcript: 'Hello, this is a test of the third eye text to speech system.'   (correct)

Result: 5 minutes β†’ 0.6s warm round-trip (500-1000x). STT is now fast enough to demo live.

Vision/TTS smoke test (modal run modal_backend.py::smoke_test):

[third-eye VISION] loaded openbmb/MiniCPM-V-2 | device=cuda:0 | dtype=torch.bfloat16
[third-eye VISION] chat: 3.85s
"...Prices range from $6 for a soup to $18 for grilled fish, with mango lassi priced at $5."

Result: greedy sampling=False works (no refusal); $18 read correctly (was $20); mango lassi spelled correctly (was MANGOLAISSI); all three models confirmed on cuda + bf16.

Diagnostic safety net: if device=cpu ever appears in the STT log, the STT image installed a CPU-only torch β€” fix by pinning a CUDA wheel: pip_install("torch>=2.5", index_url="https://download.pytorch.org/whl/cu124"). (Not needed currently β€” verified cuda:0.)