Compare commits
28 Commits
afc4dd9fd9
...
eb78df8671
| Author | SHA1 | Date | |
|---|---|---|---|
| eb78df8671 | |||
| c6087ccc80 | |||
| 0eb7671ce9 | |||
| 6115c1a3c1 | |||
| 1d5193f946 | |||
| eecc7db671 | |||
| e4c437d5c0 | |||
| 9ac9415599 | |||
| a1b72e2d7e | |||
| da5fadcae3 | |||
| f0730389e0 | |||
| 2ebb89f113 | |||
| 1c151c0e52 | |||
| c26b2b8dbb | |||
| 3058446b7d | |||
| d6e7ccd64d | |||
| c1f7054088 | |||
| a143e27eea | |||
| 05ddb3cac5 | |||
| f0b1dd07f6 | |||
| c8ca363996 | |||
| 751794aa0e | |||
| c6a6f3b22d | |||
| ad031dee70 | |||
| 966fd7af5a | |||
| e6ca32c896 | |||
| 7e18397527 | |||
| b2f80c436f |
8
.env.example
Normal file
8
.env.example
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Clé secrète Open WebUI (générer avec: openssl rand -hex 32)
|
||||||
|
WEBUI_SECRET_KEY=your_secret_key_here
|
||||||
|
|
||||||
|
# IP publique de ta VM Vast.ai (change à chaque nouvelle instance)
|
||||||
|
WEBUI_URL=http://YOUR_VAST_AI_IP
|
||||||
|
|
||||||
|
# Token du tunnel Cloudflare
|
||||||
|
CF_TUNNEL_TOKEN=your_cloudflare_tunnel_token
|
||||||
9
.gitignore
vendored
9
.gitignore
vendored
@ -1,13 +1,16 @@
|
|||||||
# Modèles IA (Trop lourds pour Git)
|
# Modèles IA (Trop lourds pour Git)
|
||||||
models/
|
models/*
|
||||||
|
!.gitkeep
|
||||||
*.ckpt
|
*.ckpt
|
||||||
*.safetensors
|
*.safetensors
|
||||||
*.pth
|
*.pth
|
||||||
*.bin
|
*.bin
|
||||||
|
|
||||||
# Données et sorties
|
# Données et sorties
|
||||||
data/
|
data/*
|
||||||
outputs/
|
!.gitkeep
|
||||||
|
outputs/*
|
||||||
|
!.gitkeep
|
||||||
*.wav
|
*.wav
|
||||||
*.mp4
|
*.mp4
|
||||||
*.png
|
*.png
|
||||||
|
|||||||
118
README.md
118
README.md
@ -1,3 +1,117 @@
|
|||||||
# Studio-IA-Modulaire
|
# 🎙️ Feuille de Route : Studio IA Multimodal v3 (2026)
|
||||||
|
|
||||||
deploiement de modeles ad hoc sur vast.ai
|
**Architecture :** Micro-services isolés via Docker Compose sur VM Vast.ai.
|
||||||
|
**Objectif :** Modularité totale, isolation des dépendances et orchestration par LLM.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧱 Principe des couches
|
||||||
|
|
||||||
|
```
|
||||||
|
VM Vast.ai (Ubuntu 22.04 bare) ← Système hôte, Docker Engine
|
||||||
|
└── NVIDIA Container Toolkit ← Pont GPU → containers
|
||||||
|
├── container open-webui FROM python:3.11-slim
|
||||||
|
├── container ollama FROM ollama/ollama:latest
|
||||||
|
├── container ace-step FROM nvcr.io/nvidia/pytorch:26.01-py3
|
||||||
|
├── container heart-mula FROM nvcr.io/nvidia/pytorch:25.08-py3 *
|
||||||
|
├── container zonos FROM nvcr.io/nvidia/pytorch:26.01-py3
|
||||||
|
├── container indextts FROM nvcr.io/nvidia/pytorch:26.01-py3
|
||||||
|
├── container hunyuan-foley FROM nvcr.io/nvidia/pytorch:25.08-py3 *
|
||||||
|
└── container comfyui FROM nvcr.io/nvidia/pytorch:26.01-py3
|
||||||
|
```
|
||||||
|
|
||||||
|
> `*` Version NGC différente si le modèle l'exige — chaque container est indépendant.
|
||||||
|
|
||||||
|
### Règles d'image de base
|
||||||
|
|
||||||
|
| Niveau | Image | Raison |
|
||||||
|
|---|---|---|
|
||||||
|
| **VM hôte** | Ubuntu 22.04 bare | Docker Engine + drivers NVIDIA |
|
||||||
|
| **Services GPU** | `nvcr.io/nvidia/pytorch:XX.XX-py3` | CUDA + PyTorch + cuDNN pré-validés par NVIDIA |
|
||||||
|
| **Services sans GPU** | `python:3.11-slim` | Léger, inutile d'embarquer CUDA |
|
||||||
|
|
||||||
|
> La version NGC (`26.01`, `25.08`...) peut différer par service selon les besoins de compatibilité.
|
||||||
|
> C'est précisément l'avantage des microservices : chaque container est une décision indépendante.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏗️ Phase 1 — Préparation de l'Infrastructure (Le Socle)
|
||||||
|
|
||||||
|
> L'objectif est de préparer le terrain pour que les containers puissent discuter entre eux sur un réseau privé.
|
||||||
|
|
||||||
|
- [ ] **Dépôt Gitea** : Structurer l'arborescence du projet
|
||||||
|
- `/services` : Un sous-dossier par micro-service (Dockerfile + code API)
|
||||||
|
- `/models` : Scripts Shell de téléchargement des poids (HuggingFace / CivitAI)
|
||||||
|
- `/data` : Volumes Docker persistants pour les sorties (`outputs/`) et les données modèles
|
||||||
|
|
||||||
|
- [ ] **Script de Provisioning** : Écrire le `provisioning_script.sh` pour Vast.ai
|
||||||
|
- Installation automatisée de Docker Engine & NVIDIA Container Toolkit
|
||||||
|
- Clonage du dépôt Git
|
||||||
|
- Configuration des permissions et création des dossiers de stockage
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🍳 Phase 2 — Build des Micro-Services (Les Cuisines)
|
||||||
|
|
||||||
|
> Chaque service est construit indépendamment pour garantir une stabilité totale.
|
||||||
|
|
||||||
|
- [ ] **Service Orchestrateur** : Configurer l'image officielle Ollama *(Gestion des LLM)*
|
||||||
|
- [ ] **Service Interface** : Configurer l'image Open WebUI *(La "Glue" utilisateur)*
|
||||||
|
- [ ] **Service Audio — ACE-Step** : Créer le Dockerfile + l'API Python (Gradio/FastAPI)
|
||||||
|
- [ ] **Service Voix — Zonos** : Créer le Dockerfile dédié *(Environnement Python 3.11+)*
|
||||||
|
- [ ] **Service Image — ComfyUI** : Préparer l'image optimisée pour Flux.1 et SDXL
|
||||||
|
- [ ] **Service Foley — Hunyuan** : Créer le service spécifique pour le bruitage vidéo synchronisé
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎼 Phase 3 — Orchestration (Le Chef d'Orchestre)
|
||||||
|
|
||||||
|
> Utilisation de Docker Compose pour lier les services sur une seule machine.
|
||||||
|
|
||||||
|
- [ ] **Fichier `docker-compose.yml`**
|
||||||
|
- Définir le réseau interne `studio-network`
|
||||||
|
- Assigner les ressources GPU via `deploy.resources.reservations`
|
||||||
|
- Mapper les ports : `3000` (public) pour le WebUI, les autres en accès restreint
|
||||||
|
|
||||||
|
- [ ] **Gestion de la VRAM & RAM**
|
||||||
|
- Implémenter des limites mémoire par container
|
||||||
|
- Configurer le swap pour éviter les crashs lors des chargements de modèles lourds
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔌 Phase 4 — Connexion de la "Glue" (Le Câblage)
|
||||||
|
|
||||||
|
> Configuration de l'intelligence centrale pour piloter les outils.
|
||||||
|
|
||||||
|
- [ ] **Configuration Ollama** : Connecter Open WebUI au container LLM via `http://ollama:11434`
|
||||||
|
|
||||||
|
- [ ] **Développement des "Functions"** : Coder les ponts Python internes à Open WebUI vers :
|
||||||
|
- `http://ace-step:7860` — Musique
|
||||||
|
- `http://zonos:7862` — Voix
|
||||||
|
- `http://comfyui:8188` — Image
|
||||||
|
- `http://hunyuan-foley:7864` — Foley
|
||||||
|
|
||||||
|
- [ ] **System Prompt** : Configurer l'assistant "Studio Manager" pour qu'il route les requêtes vers les bons services
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Phase 5 — Optimisation & Production
|
||||||
|
|
||||||
|
> Passage à l'échelle et fluidification de l'expérience.
|
||||||
|
|
||||||
|
- [ ] **Téléchargement des modèles** : Finaliser les scripts `download_models.sh`
|
||||||
|
*(utilisation de `wget -c` pour la reprise sur erreur)*
|
||||||
|
|
||||||
|
- [ ] **Persistance** : Valider le montage des volumes pour que les fichiers générés soient accessibles hors des containers
|
||||||
|
|
||||||
|
- [ ] **Snapshot final** : Une fois la configuration stable, créer un Snapshot Vast.ai pour un déploiement instantané *(Warm Boot)*
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠️ Pourquoi cette architecture gagne en 2026
|
||||||
|
|
||||||
|
| Avantage | Détail technique |
|
||||||
|
|---|---|
|
||||||
|
| **Modularité** | Tu veux changer de modèle de voix ? Tu mets à jour 1 seul container sans toucher au reste. |
|
||||||
|
| **Résilience** | Si le service d'image plante, tu peux toujours chatter et générer de la musique. |
|
||||||
|
| **Scalabilité** | Demain, tu peux mettre Ollama sur un GPU et ACE-Step sur un autre sans réécrire le code. |
|
||||||
0
data/.gitkeep
Normal file
0
data/.gitkeep
Normal file
102
docker-compose.yml
Normal file
102
docker-compose.yml
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
services:
|
||||||
|
# --- LE PORTIER ---
|
||||||
|
gateway:
|
||||||
|
image: nginx:latest
|
||||||
|
container_name: studio-gateway-1
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
volumes:
|
||||||
|
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
|
||||||
|
networks:
|
||||||
|
- studio-net
|
||||||
|
depends_on:
|
||||||
|
open-webui:
|
||||||
|
condition: service_healthy
|
||||||
|
audio-api:
|
||||||
|
condition: service_started
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
# --- LE TUNNEL HTTPS ---
|
||||||
|
cloudflared:
|
||||||
|
image: cloudflare/cloudflared:latest
|
||||||
|
container_name: studio-cloudflared
|
||||||
|
command: tunnel --no-autoupdate run --token ${CF_TUNNEL_TOKEN}
|
||||||
|
environment:
|
||||||
|
- CF_TUNNEL_TOKEN=${CF_TUNNEL_TOKEN}
|
||||||
|
networks:
|
||||||
|
- studio-net
|
||||||
|
depends_on:
|
||||||
|
- gateway
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
# --- L'INTERFACE (Open WebUI) ---
|
||||||
|
open-webui:
|
||||||
|
image: ghcr.io/open-webui/open-webui:main
|
||||||
|
container_name: open-webui
|
||||||
|
environment:
|
||||||
|
- OLLAMA_BASE_URL=http://ollama:11434
|
||||||
|
- WEBUI_SECRET_KEY=${WEBUI_SECRET_KEY}
|
||||||
|
- WEBUI_URL=${WEBUI_URL}
|
||||||
|
- ENABLE_WEBSOCKETS=True
|
||||||
|
volumes:
|
||||||
|
- webui_data:/app/backend/data
|
||||||
|
networks:
|
||||||
|
- studio-net
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
# --- LE CERVEAU (Ollama) ---
|
||||||
|
ollama:
|
||||||
|
image: ollama/ollama:latest
|
||||||
|
container_name: ollama
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
reservations:
|
||||||
|
devices:
|
||||||
|
- driver: nvidia
|
||||||
|
count: all
|
||||||
|
capabilities: [gpu]
|
||||||
|
volumes:
|
||||||
|
- ollama_data:/root/.ollama
|
||||||
|
networks:
|
||||||
|
- studio-net
|
||||||
|
expose:
|
||||||
|
- "11434"
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
# --- LE SERVICE AUDIO ---
|
||||||
|
audio-api:
|
||||||
|
build:
|
||||||
|
context: ./services/audio-api
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: audio-api
|
||||||
|
environment:
|
||||||
|
- NVIDIA_VISIBLE_DEVICES=all
|
||||||
|
- PYTHONUNBUFFERED=1
|
||||||
|
entrypoint: ["python3.11", "/app/server.py"]
|
||||||
|
volumes:
|
||||||
|
- ./services/audio-api:/app
|
||||||
|
- ./models:/app/models
|
||||||
|
- ./outputs:/app/outputs
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
reservations:
|
||||||
|
devices:
|
||||||
|
- driver: nvidia
|
||||||
|
count: all
|
||||||
|
capabilities: [gpu]
|
||||||
|
ports:
|
||||||
|
- "7860:7860"
|
||||||
|
networks:
|
||||||
|
- studio-net
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
studio-net:
|
||||||
|
driver: bridge
|
||||||
|
volumes:
|
||||||
|
webui_data:
|
||||||
|
ollama_data:
|
||||||
0
models/.gitkeep
Normal file
0
models/.gitkeep
Normal file
52
nginx/default.conf
Normal file
52
nginx/default.conf
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
|
||||||
|
# --- TRANSCRIPTION AUDIO (STT) ---
|
||||||
|
# Doit être AVANT location / pour avoir la priorité
|
||||||
|
location /api/v1/audio/transcriptions {
|
||||||
|
proxy_pass http://audio-api:7860/v1/audio/transcriptions;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_read_timeout 600s;
|
||||||
|
proxy_send_timeout 600s;
|
||||||
|
client_max_body_size 25M;
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- API AUDIO (accès direct Gradio/FastAPI) ---
|
||||||
|
location /audio/ {
|
||||||
|
proxy_pass http://audio-api:7860/;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_read_timeout 600s;
|
||||||
|
client_max_body_size 25M;
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- INTERFACE PRINCIPALE & FLUX OLLAMA ---
|
||||||
|
location / {
|
||||||
|
proxy_pass http://open-webui:8080;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
|
# INDISPENSABLE POUR LES WEBSOCKETS
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
|
||||||
|
# DÉSACTIVATION TOTALE DU CACHE ET DU BUFFER
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_cache off;
|
||||||
|
chunked_transfer_encoding on;
|
||||||
|
|
||||||
|
# Temps d'attente rallongé pour les gros modèles
|
||||||
|
proxy_read_timeout 600s;
|
||||||
|
proxy_send_timeout 600s;
|
||||||
|
client_max_body_size 25M;
|
||||||
|
}
|
||||||
|
}
|
||||||
0
outputs/.gitkeep
Normal file
0
outputs/.gitkeep
Normal file
28
provisioning_script.sh
Normal file
28
provisioning_script.sh
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 1. Mise à jour du système et installation des outils de base
|
||||||
|
apt-get update && apt-get install -y git docker-compose-v2 nvidia-container-toolkit
|
||||||
|
|
||||||
|
# 2. Se placer dans le répertoire racine de Vast.ai
|
||||||
|
cd /root
|
||||||
|
|
||||||
|
# 3. Cloner ton dépôt Gitea (Public)
|
||||||
|
# Remplace l'URL par la tienne si nécessaire
|
||||||
|
git clone https://git.syoul.fr/SIAM/Studio-IA-Modulaire.git studio
|
||||||
|
|
||||||
|
# 4. Entrer dans le projet
|
||||||
|
cd studio
|
||||||
|
|
||||||
|
# 5. Créer le fichier .env si il n'existe pas (pour éviter les erreurs Docker)
|
||||||
|
if [ ! -f .env ]; then
|
||||||
|
echo "WEBUI_SECRET_KEY=nicoboy_studio_2026" > .env
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 6. Lancer l'architecture en arrière-plan
|
||||||
|
# --build force la construction de ton Dockerfile audio-api
|
||||||
|
docker compose up -d --build
|
||||||
|
|
||||||
|
echo "-------------------------------------------------------"
|
||||||
|
echo "🚀 Studio lancé ! Attends 2-3 min que les images se téléchargent."
|
||||||
|
echo "Accède à Open WebUI sur le port 3000 de ton IP Vast.ai"
|
||||||
|
echo "-------------------------------------------------------"
|
||||||
37
scripts/webui/audio_action.py
Normal file
37
scripts/webui/audio_action.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
|
class Action:
|
||||||
|
def __init__(self):
|
||||||
|
# L'URL interne au réseau Docker défini dans ton compose
|
||||||
|
self.api_url = "http://audio-api:7860/api/predict"
|
||||||
|
|
||||||
|
async def action(self, body: dict, __user__: dict = None, __event_emitter__=None):
|
||||||
|
# 1. Récupérer le dernier message (le prompt)
|
||||||
|
last_message = body['messages'][-1]['content']
|
||||||
|
|
||||||
|
await __event_emitter__({
|
||||||
|
"type": "status",
|
||||||
|
"data": {"description": "🎵 Génération de la musique en cours...", "done": False}
|
||||||
|
})
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 2. Appel au container Audio-API (Gradio/FastAPI)
|
||||||
|
response = requests.post(self.api_url, json={
|
||||||
|
"data": [last_message, 10] # Prompt + Durée
|
||||||
|
}, timeout=120)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
result = response.json()
|
||||||
|
file_url = result['data'][0] # Chemin du .wav généré
|
||||||
|
|
||||||
|
await __event_emitter__({
|
||||||
|
"type": "status",
|
||||||
|
"data": {"description": "✅ Musique prête !", "done": True}
|
||||||
|
})
|
||||||
|
|
||||||
|
# 3. Envoyer le lien du fichier à l'étudiant
|
||||||
|
return f"Voici votre création : {file_url}"
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return f"❌ Erreur de connexion au studio audio : {str(e)}"
|
||||||
40
services/audio-api/Dockerfile
Normal file
40
services/audio-api/Dockerfile
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# Utilisation d'une image stable avec support GPU
|
||||||
|
FROM nvidia/cuda:12.1.1-cudnn8-runtime-ubuntu22.04
|
||||||
|
|
||||||
|
# Configuration environnement
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Installation des dépendances système (Audio + Python 3.11)
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
python3.11 \
|
||||||
|
python3-pip \
|
||||||
|
ffmpeg \
|
||||||
|
libsndfile1 \
|
||||||
|
git \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Mise à jour de pip pour éviter les avertissements
|
||||||
|
RUN python3.11 -m pip install --upgrade pip
|
||||||
|
|
||||||
|
# 1. Installer PyTorch avec le lien direct CUDA 12.1
|
||||||
|
# On utilise "python3.11 -m pip" pour garantir que Gradio sera trouvé par Python 3.11
|
||||||
|
RUN python3.11 -m pip install --no-cache-dir \
|
||||||
|
torch torchvision torchaudio \
|
||||||
|
--index-url https://download.pytorch.org/whl/cu121
|
||||||
|
|
||||||
|
# 2. Installer le reste des dépendances
|
||||||
|
RUN python3.11 -m pip install --no-cache-dir \
|
||||||
|
fastapi \
|
||||||
|
uvicorn \
|
||||||
|
gradio \
|
||||||
|
faster-whisper
|
||||||
|
|
||||||
|
# Copie du code serveur (sera écrasé par le volume en dev, mais utile pour le build)
|
||||||
|
COPY server.py .
|
||||||
|
|
||||||
|
# Exposition du port Gradio
|
||||||
|
EXPOSE 7860
|
||||||
|
|
||||||
|
# Lancement explicite avec Python 3.11
|
||||||
|
CMD ["python3.11", "server.py"]
|
||||||
35
services/audio-api/server.py
Normal file
35
services/audio-api/server.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
from fastapi import FastAPI, UploadFile, File, HTTPException
|
||||||
|
from faster_whisper import WhisperModel
|
||||||
|
import io
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
# Chargement du modèle sur ton GPU RTX 4060 Ti
|
||||||
|
# On utilise "cuda" et "float16" pour la vitesse maximale
|
||||||
|
model = WhisperModel("base", device="cuda", compute_type="float16")
|
||||||
|
|
||||||
|
@app.get("/v1/models")
|
||||||
|
async def get_models():
|
||||||
|
# Indispensable pour qu'Open WebUI voie le modèle dans la liste
|
||||||
|
return {"data": [{"id": "whisper-1"}]}
|
||||||
|
|
||||||
|
@app.post("/v1/audio/transcriptions")
|
||||||
|
async def transcribe(file: UploadFile = File(...)):
|
||||||
|
try:
|
||||||
|
# On lit le fichier envoyé par le micro
|
||||||
|
audio_data = await file.read()
|
||||||
|
audio_file = io.BytesIO(audio_data)
|
||||||
|
|
||||||
|
# Transcription ultra-rapide avec ton GPU
|
||||||
|
segments, _ = model.transcribe(audio_file, beam_size=5)
|
||||||
|
text = " ".join([segment.text for segment in segments])
|
||||||
|
|
||||||
|
return {"text": text}
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Erreur transcription: {e}")
|
||||||
|
raise HTTPException(status_code=500, detail=str(e))
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import uvicorn
|
||||||
|
# On lance sur le port 7860 comme prévu dans ton Docker-compose
|
||||||
|
uvicorn.run(app, host="0.0.0.0", port=7860)
|
||||||
Reference in New Issue
Block a user