| --- |
| title: TuringDNA Assistant |
| emoji: 𧬠|
| colorFrom: gray |
| colorTo: blue |
| sdk: gradio |
| sdk_version: 4.44.0 |
| app_file: app.py |
| pinned: false |
| license: apache-2.0 |
| hardware: zero-a10g |
| short_description: Protein biology Q&A backend for the TuringDNA engine. |
| suggested_hardware: zero-a10g |
| --- |
| |
| # TuringDNA Assistant |
|
|
| Self-hosted biomedical LLM that powers the in-app chat panel on |
| [turingdna.com/app](https://turingdna.com/app). Loads **BioMistral-7B** |
| (an open-source Mistral fine-tuned on biomedical corpora) on a |
| ZeroGPU-shared NVIDIA A100, exposes a Gradio `ChatInterface` for direct |
| testing, and an auto-generated `/run/predict` API the Flask app calls |
| via `gradio_client`. |
|
|
| ## Architecture |
|
|
| ``` |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ |
| β winter4000/syntheogenesis (Flask + vanilla JS, CPU) β |
| β βββ dee/server.py /api/chat β |
| β βββ gradio_client.predict() βββββββββββββββββββββββββββ β |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββ |
| βΌ |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ |
| β winter4000/turingdna-assistant (Gradio, ZeroGPU) β |
| β βββ app.py Gradio ChatInterface β |
| β βββ llm.py BioMistral-7B in bf16, @spaces.GPU(duration=60) β |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ |
| ``` |
|
|
| Two-Space split so the existing Flask engine doesn't need a rewrite and |
| the model lives where the GPU does. |
|
|
| ## Why ZeroGPU? |
|
|
| ZeroGPU gives shared A100 access to HF PRO subscribers at no per-hour |
| cost (just the $9/mo subscription). The decorator pattern: |
| - Model loads on CPU at import (~14 GB in bf16, fits comfortably in |
| ZeroGPU's 60 GB host RAM) |
| - `@spaces.GPU(duration=60)` moves the model to GPU only during a |
| generation call, then releases β so we share the A100 efficiently |
| with other ZeroGPU Spaces |
|
|
| First call after the Space wakes up: ~10β30 s (cold-start + GPU acquire). |
| Subsequent calls: ~25β80 tokens/sec. |
|
|
| ## Model |
|
|
| [BioMistral/BioMistral-7B](https://huggingface.co/BioMistral/BioMistral-7B) |
| β Apache-2.0, biomedical-domain fine-tune of Mistral-7B-Instruct-v0.1. |
| Knows enzyme mechanisms, active sites, conserved domains, codon |
| optimization, expression systems, and cloning vocab better than vanilla |
| Mistral. Same Mistral instruct template (`[INST] ... [/INST]`). |
|
|
| Fallback if BioMistral fetch fails: `mistralai/Mistral-7B-Instruct-v0.2`. |
|
|
| ## System prompt |
|
|
| Baked into `llm.py`. The assistant is told it's the chat backend for |
| TuringDNA, knows the codebase's ΞLL sign convention (positive ΞLL = |
| mutation is MORE likely than WT under ESM-2, i.e. more tolerated; |
| negative = less likely, i.e. disruptive), and is instructed to be |
| concise + not hallucinate domain boundaries. |
|
|
| ## Local development |
|
|
| ```bash |
| pip install -r requirements.txt |
| python app.py |
| ``` |
|
|
| Local runs use CPU-only fp16 (~2 tok/s on Mac M1, ~1 tok/s on Intel |
| Mac). Production runs on ZeroGPU A100. The `@spaces.GPU` decorator |
| is a no-op locally so the same code works in both contexts. |
|
|
| ## Calling from outside |
|
|
| ```python |
| from gradio_client import Client |
| |
| client = Client("winter4000/turingdna-assistant") |
| response = client.predict( |
| message="What does a ΞLL of +1.2 for V8L mean?", |
| history=[], |
| api_name="/chat", |
| ) |
| print(response) |
| ``` |
|
|
| ## Files |
|
|
| - `app.py` β Gradio app entry (ChatInterface + Gradio launches its own |
| API endpoints) |
| - `llm.py` β model loading + Mistral prompt formatting + ZeroGPU |
| inference function |
| - `requirements.txt` β Gradio, transformers, spaces, torch, accelerate |
| - `README.md` β this file (also the HF Space metadata via YAML |
| frontmatter at the top) |
|
|