EuropaLex / README.md
Takosaga's picture
Update README.md
65b53f3 verified
|
Raw
History Blame Contribute Delete
5.89 kB
---
title: EuropaLex
emoji: πŸ“š
colorFrom: blue
colorTo: indigo
sdk: docker
sdk_version: "latest"
python_version: "3.12"
app_file: app.py
pinned: false
tags:
- track:backyard
- sponsor:openbmb
- achievement:offgrid
- achievement:offbrand
- achievement:llama
- achievement:sharing
---
# EuropaLex β€” Docker / Hugging Face Spaces Deployment
AI-powered flashcard generator for European languages, deployed as a Docker container on [Hugging Face Spaces](https://huggingface.co/spaces). All four AI models are baked into the image at build time β€” the app starts instantly with zero wait.
> **CPU-only inference:** All inference runs on CPU. Expect slower performance (30+ seconds per sentence for translation, longer for TTS/images) in exchange for free hosting.
## Model weights
| Model | HF Hub Repo | GGUF File | Runtime | Params | Size | Role |
|---|---|---|---|---|---|---|
| MiniCPM5-1B Q8_0 | [Abiray/MiniCPM5-1B-GGUF](https://huggingface.co/Abiray/MiniCPM5-1B-GGUF) | `minicpm5-1b-Q8_0.gguf` | llama-cpp-python | 1.08 B | ~1.1 GB | English text generation (Phase 1) |
| tiny-aya-water Q4_K_M | [CohereLabs/tiny-aya-water-GGUF](https://huggingface.co/CohereLabs/tiny-aya-water-GGUF) | `tiny-aya-water-q4_k_m.gguf` | llama-cpp-python | 3.35 B | ~2.1 GB | Translation (active) |
| OmniVoice Q8_0 (base + tokenizer) | [Serveurperso/OmniVoice-GGUF](https://huggingface.co/Serveurperso/OmniVoice-GGUF) | `omnivoice-base-Q8_0.gguf` + `omnivoice-tokenizer-Q8_0.gguf` | omnivoice.cpp | 0.6 B | ~950 MB | Text-to-speech |
| FLUX.2-klein 4B Q4_K_M | [unsloth/FLUX.2-klein-4B-GGUF](https://huggingface.co/unsloth/FLUX.2-klein-4B-GGUF) | `flux-2-klein-4b-Q4_K_M.gguf` | diffusers | 4 B | ~2.6 GB | Image generation |
## Links
[Social Media Post](https://www.linkedin.com/posts/gonzalo-gamez_buildsmallhackathon-huggingface-ai-activity-7472322421472051200-iUBa/?rcm=ACoAADjnxE4BIBmKXlLcq6ecaJUWIc8fuJGMb9g)
[Traces](https://huggingface.co/datasets/Takosaga/EuropaLex-session-traces)
[Demo Video](https://youtu.be/OVBDAwCTuxk)
The demo works on my machine, two days to figure out how to deploy and still was stuck.
## How It Works
```
Docker build:
python:3.12-slim β†’ pip install CPU deps β†’ huggingface-cli login (build secret) β†’ download all models β†’ CMD ["python", "app.py"]
HF Spaces runtime:
Container starts β†’ _auto_download_models() finds GGUF files β†’ skips download β†’ launches Gradio on :7860
```
The Dockerfile downloads all models during `docker build` using your HF token as a build secret. At runtime, the app detects pre-existing model files and skips download entirely β€” no authentication needed, no waiting.
## CPU Performance Expectations
| Operation | Expected Time |
|---|---|
| Phase 1: Generate 3 English sentences | ~30–60 seconds |
| Phase 2: Translate 3 sentences (tiny-aya) | ~1–3 minutes |
| Phase 2: TTS audio per sentence | ~5–15 seconds |
| Phase 2: Image generation per card | ~30–60+ seconds |
These are approximate and depend on the HF Spaces CPU tier. All features remain functional β€” just slower than a GPU setup.
## Local Docker Testing (Optional)
Build and test locally before deploying:
```bash
# Build the image (requires your HF token)
docker build \
--secret id=hf_token,env=HUGGING_FACE_HUB_TOKEN \
-t europalex .
# Run locally (port 7860)
docker run -p 7860:7860 europalex
```
The container serves Gradio on `http://localhost:7860`. Press Ctrl+C to stop.
## Architecture
EuropaLex uses a two-phase generation workflow:
1. **Phase 1** β€” Enter a scenario, select CEFR level (A0–C2), set batch size β†’ MiniCPM5-1B generates English sentences
2. **Phase 2** β€” Select target language, toggle Audio/Images β†’ tiny-aya translates, OmniVoice generates TTS, FLUX generates illustrations
Cards export as Anki `.apkg` files or zipped CSV folders with flat media files.
## Repository Structure
```
EuropaLex/
β”œβ”€β”€ Dockerfile # Single-stage build: deps + model download + Gradio launch
β”œβ”€β”€ .dockerignore # Exclude .venv, .git, models from build context
β”œβ”€β”€ README.md # This file β€” HF Spaces deployment guide
β”œβ”€β”€ app.py # Entry point β€” Gradio UI wiring, two-phase generation handlers
β”œβ”€β”€ pyproject.toml # Project config (uv)
β”œβ”€β”€ requirements.txt # pip install dependencies
β”œβ”€β”€ configs/settings.yaml # App settings, model paths, batch defaults
β”œβ”€β”€ core/ # Business logic
β”‚ β”œβ”€β”€ types.py # Pydantic models: CardData, CEFRLevel, TextResult, etc.
β”‚ β”œβ”€β”€ engine.py # MiniCPMTextEngine, LlamaCppTextEngine, EnginePool
β”‚ β”œβ”€β”€ audio_gen.py # TTSEngine (OmniVoice)
β”‚ β”œβ”€β”€ image_gen.py # ImageGenEngine (diffusers Flux2KleinPipeline)
β”‚ β”œβ”€β”€ text_gen.py # Sentence extraction + generation with retry loop
β”‚ └── pipeline.py # Phase 2 translation orchestration
β”œβ”€β”€ frontend/ # Gradio 6 UI
β”‚ β”œβ”€β”€ ui/
β”‚ β”‚ β”œβ”€β”€ widgets.py # Styled toggle checkbox wrappers, Blocks builder
β”‚ β”‚ └── cards.py # Card rendering, gallery layout, progress bar
β”‚ └── css/custom.css # Plain-white theme, card styling, disabled states
β”œβ”€β”€ models/
β”‚ └── download_models.py # HF Hub model downloader (runtime fallback)
β”œβ”€β”€ export/ # Export formats
β”‚ β”œβ”€β”€ apkg_export.py # Anki .apkg export via genanki
β”‚ β”œβ”€β”€ csv_export.py # CSV zip export with flat media files
β”‚ └── anki_tunnel.py # MCP tunnel sync for live Anki import
β”œβ”€β”€ docs/ # Design specs and implementation plans
β”‚ └── superpowers/ # Planning documents
└── tests/ # Test suite (pytest)
```