Compare commits
28 Commits
5e2ace4829
...
main
| 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
|
||||||
@ -16,14 +16,27 @@ services:
|
|||||||
condition: service_started
|
condition: service_started
|
||||||
restart: always
|
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) ---
|
# --- L'INTERFACE (Open WebUI) ---
|
||||||
open-webui:
|
open-webui:
|
||||||
image: ghcr.io/open-webui/open-webui:main
|
image: ghcr.io/open-webui/open-webui:main
|
||||||
container_name: open-webui
|
container_name: open-webui
|
||||||
environment:
|
environment:
|
||||||
- OLLAMA_BASE_URL=http://ollama:11434
|
- OLLAMA_BASE_URL=http://ollama:11434
|
||||||
- WEBUI_SECRET_KEY=${WEBUI_SECRET_KEY:-supersecretkey}
|
- WEBUI_SECRET_KEY=${WEBUI_SECRET_KEY}
|
||||||
- WEBUI_URL=http://93.108.34.236
|
- WEBUI_URL=${WEBUI_URL}
|
||||||
- ENABLE_WEBSOCKETS=True
|
- ENABLE_WEBSOCKETS=True
|
||||||
volumes:
|
volumes:
|
||||||
- webui_data:/app/backend/data
|
- webui_data:/app/backend/data
|
||||||
@ -51,6 +64,8 @@ services:
|
|||||||
- ollama_data:/root/.ollama
|
- ollama_data:/root/.ollama
|
||||||
networks:
|
networks:
|
||||||
- studio-net
|
- studio-net
|
||||||
|
expose:
|
||||||
|
- "11434"
|
||||||
restart: always
|
restart: always
|
||||||
|
|
||||||
# --- LE SERVICE AUDIO ---
|
# --- LE SERVICE AUDIO ---
|
||||||
@ -59,11 +74,9 @@ services:
|
|||||||
context: ./services/audio-api
|
context: ./services/audio-api
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
container_name: audio-api
|
container_name: audio-api
|
||||||
# Force Python à sortir les logs immédiatement
|
|
||||||
environment:
|
environment:
|
||||||
- NVIDIA_VISIBLE_DEVICES=all
|
- NVIDIA_VISIBLE_DEVICES=all
|
||||||
- PYTHONUNBUFFERED=1
|
- PYTHONUNBUFFERED=1
|
||||||
# On utilise le chemin absolu dans le container pour être sûr
|
|
||||||
entrypoint: ["python3.11", "/app/server.py"]
|
entrypoint: ["python3.11", "/app/server.py"]
|
||||||
volumes:
|
volumes:
|
||||||
- ./services/audio-api:/app
|
- ./services/audio-api:/app
|
||||||
@ -76,14 +89,14 @@ services:
|
|||||||
- driver: nvidia
|
- driver: nvidia
|
||||||
count: all
|
count: all
|
||||||
capabilities: [gpu]
|
capabilities: [gpu]
|
||||||
|
ports:
|
||||||
|
- "7860:7860"
|
||||||
networks:
|
networks:
|
||||||
- studio-net
|
- studio-net
|
||||||
restart: always
|
restart: always
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
studio-net:
|
studio-net:
|
||||||
driver: bridge
|
driver: bridge
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
webui_data:
|
webui_data:
|
||||||
ollama_data:
|
ollama_data:
|
||||||
@ -1,31 +1,20 @@
|
|||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
|
|
||||||
# Interface principale & Flux Ollama
|
# --- TRANSCRIPTION AUDIO (STT) ---
|
||||||
location / {
|
# Doit être AVANT location / pour avoir la priorité
|
||||||
proxy_pass http://open-webui:8080;
|
location /api/v1/audio/transcriptions {
|
||||||
|
proxy_pass http://audio-api:7860/v1/audio/transcriptions;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
|
|
||||||
# --- AJOUT INDISPENSABLE POUR LES WEBSOCKETS ---
|
|
||||||
proxy_http_version 1.1; ## Requis
|
|
||||||
proxy_set_header Upgrade $http_upgrade; ## Requis
|
|
||||||
proxy_set_header Connection "upgrade"; ## Requis
|
|
||||||
# -----------------------------------------------
|
|
||||||
|
|
||||||
# DESACTIVATION TOTALE DU CACHE ET DU BUFFER
|
|
||||||
proxy_buffering off;
|
proxy_buffering off;
|
||||||
proxy_cache off;
|
|
||||||
chunked_transfer_encoding on;
|
|
||||||
|
|
||||||
# Temps d'attente rallongé pour les gros modèles
|
|
||||||
proxy_read_timeout 600s;
|
proxy_read_timeout 600s;
|
||||||
proxy_send_timeout 600s;
|
proxy_send_timeout 600s;
|
||||||
|
client_max_body_size 25M;
|
||||||
}
|
}
|
||||||
|
|
||||||
# API Audio
|
# --- API AUDIO (accès direct Gradio/FastAPI) ---
|
||||||
location /audio/ {
|
location /audio/ {
|
||||||
proxy_pass http://audio-api:7860/;
|
proxy_pass http://audio-api:7860/;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
@ -34,5 +23,30 @@ server {
|
|||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_buffering off;
|
proxy_buffering off;
|
||||||
proxy_read_timeout 600s;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,19 +1,35 @@
|
|||||||
import gradio as gr
|
from fastapi import FastAPI, UploadFile, File, HTTPException
|
||||||
import time
|
from faster_whisper import WhisperModel
|
||||||
|
import io
|
||||||
|
|
||||||
def generate_music(prompt, duration):
|
app = FastAPI()
|
||||||
print(f"🎵 Génération demandée : {prompt} pour {duration} secondes")
|
|
||||||
# Simule un temps de calcul
|
|
||||||
time.sleep(2)
|
|
||||||
return "Dummy audio generated !"
|
|
||||||
|
|
||||||
# Interface pour Open WebUI
|
# Chargement du modèle sur ton GPU RTX 4060 Ti
|
||||||
demo = gr.Interface(
|
# On utilise "cuda" et "float16" pour la vitesse maximale
|
||||||
fn=generate_music,
|
model = WhisperModel("base", device="cuda", compute_type="float16")
|
||||||
inputs=["text", "number"],
|
|
||||||
outputs="text",
|
@app.get("/v1/models")
|
||||||
title="ACE-Step Audio API"
|
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__":
|
if __name__ == "__main__":
|
||||||
demo.launch(server_name="0.0.0.0", server_port=7860)
|
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