File size: 6,215 Bytes
d4eb85b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
---

title: MSL Internal API v7 Part 6
emoji: 🤖
colorFrom: blue
colorTo: indigo
sdk: docker
app_port: 7860
pinned: false
license: other
---


# bert-api/

Backend Python Flask que sirve el clasificador BERT propio de MuseSceneLab para los comandos NLP de MEHEARSAL.

**Origen:** copiado de `D:\XDev.Projects\MEHEARSAL-NLP-CONTROLLER-RMIT\mehearsal_v5_and_v6\bert-api\` con 3 modificaciones mínimas para HF Spaces Docker (ver §"Adaptaciones" más abajo).

**Despliegue actual:** HuggingFace Space `MuseSceneLab/msl-internal-api-v7-part6` (Docker SDK). Ver doc 40 §6 Fase A.8-A.12.

**Modelo HF:** `MuseSceneLab/mehearsal-nlp-v7-part6` — 46 intents (16 musicales + 30 UI/UX nuevos: PLAYBACK_*, LOAD_SONG, OPEN_SETTINGS, ADD_MUSICIAN, etc.). Resuelve el gap Part 6 UX identificado en doc 38 §3.

> **Nota sobre el frontmatter YAML del principio:** lo leen los Spaces de HuggingFace para configurar el deploy (título, SDK, puerto). `app_port: 7860` es crítico — sin él HF no sabe qué puerto exponer y el Space queda en "config error". En cualquier otro contexto (lectura local, repo de GitHub) el frontmatter se ignora o se renderiza como bloque inicial.



**Despliegue futuro:** AWS App Runner cuando se cumplan los disparadores de doc 33 §13.4.



---



## Estructura



```

bert-api/

├── bert_api.py           Flask app. Carga modelo en arranque, expone /classify y /health
├── requirements.txt      flask, flask-cors, transformers, torch, huggingface_hub, python-dotenv

├── Dockerfile            Imagen para HF Spaces. Python 3.11-slim, expone 7860

├── .dockerignore         Excluye venv, __pycache__, README, etc. de la imagen

└── README.md             Este archivo

```



---



## Endpoints



| Método | Path | Body | Devuelve |

|---|---|---|---|

| `POST` | `/classify` | `{ "utterance": "mute the guitar" }` | `{ intent_label, locale, target, params_json, confidence, model }` |

| `GET` | `/health` | — | `{ status, model }` |



---



## Variables de entorno



| Var | Default | Para qué |

|---|---|---|

| `HF_TOKEN` | _(obligatorio)_ | Auth para descargar el modelo privado de HF. En HF Spaces se configura como Secret del Space |
| `BERT_MODEL_NAME` | `MuseSceneLab/mehearsal-nlp-v7-part6` | Cambiar para forzar otro modelo single-task (v5/v6/v7-part6 son compatibles, comparten arquitectura `AutoModelForSequenceClassification`) |
| `PORT` | `7860` | Puerto. Para gunicorn en el Dockerfile se hardcodea a 7860 en el flag `--bind`. Para Flask local (`python bert_api.py`) se lee de aquí |

## Servidor: gunicorn en producción, Flask dev en local

El Dockerfile lanza el backend con **gunicorn** (WSGI server productivo):

```

gunicorn --bind 0.0.0.0:7860 --workers 2 --preload --timeout 120 bert_api:app

```

- `--workers 2`: 2 procesos paralelos (CPU Basic free de HF Spaces tiene 2 vCPU).
- `--preload`: carga el modelo una vez antes de fork, los workers comparten memoria via COW. Sin esto, cada worker cargaría su copia y duplicaríamos memoria.
- `--timeout 120`: si una inferencia se cuelga, mata el worker y arranca otro. Default 30s es demasiado bajo para casos límite con torch.

Para **desarrollo local rápido** (iteración sobre `bert_api.py` sin tener que reconstruir imagen), el bloque `if __name__ == '__main__'` con `app.run()` sigue funcionando — basta con `python bert_api.py`. Esto NO se ejecuta en Spaces porque gunicorn importa `bert_api:app` directamente, sin pasar por `__main__`.

---

## Desarrollo local

```bash

cd bert-api

python -m venv venv

.\venv\Scripts\activate            # Windows PowerShell: .\venv\Scripts\Activate.ps1

pip install -r requirements.txt

$env:HF_TOKEN = "hf_..."           # tu token con permiso de lectura sobre el modelo

python bert_api.py

```

Levanta en `http://localhost:7860`. Probar con:

```bash

curl -X POST http://localhost:7860/classify -H "Content-Type: application/json" -d '{"utterance":"mute the guitar"}'

```

**Nota:** la primera ejecución descarga el modelo (~500 MB) desde HF a la caché local (`~/.cache/huggingface/`). Ejecuciones posteriores son instantáneas.

---

## Despliegue como Space (proceso R4-R7 de doc 33)

1. Crear Space en `huggingface.co/new-space`:
   - Owner: `MuseSceneLab`
   - Name: `msl-internal-api-v7-part6`
   - SDK: **Docker** (template Blank — usamos nuestro Dockerfile)
   - Hardware: CPU Basic (free)
   - Visibility: Public _(el contenedor; los pesos del modelo siguen privados)_
   - License: `other` (decisión doc 34 §D1 — IP de MSL)

2. En el Space, ir a Settings → Repository secrets → añadir `HF_TOKEN` con el token `mehearsal-read` de Jose.

3. Subir los 4 archivos vía Web UI (drag & drop en `Files → Add file → Upload files`):
   `bert_api.py`, `Dockerfile`, `requirements.txt`, `README.md`.

   > NO subir la carpeta `analisis/` — es contenido auxiliar local de MSL, no debe formar parte de la imagen Docker.

4. HF construye la imagen (~3-5 min). Verificar logs en la UI del Space.

5. URL pública: `https://musescenelab-msl-internal-api-v7-part6.hf.space/classify`.

---

## Adaptaciones respecto al código fuente

Fuente: rama `origin/part_6` del repo `MEHEARSAL-NLP-CONTROLLER-RMIT`, archivo `mehearsal_v5_and_v6/bert-api/bert_api.py` (commit `8645f5c — Add Part 6 UI UX intents`).

Tres diffs vs ese fuente:

1. **Import `os`** al principio del archivo.
2. **`MODEL_NAME` configurable** vía env var (default `v7-part6`). El fuente lo tenía hardcoded.

3. **Puerto y debug** en `app.run()`: puerto leído de env var `PORT` (default 7860, requisito de Spaces), `debug=False` para producción.



La lógica de `extract_entities()` (con las listas `musicians[]`, `views{}`, `prefixes[]` añadidas para Part 6), `INTENT_METADATA` (46 entradas) y el upgrade de intents en `/classify` está **intacta**. Esto evita cualquier divergencia funcional respecto al desarrollo RMIT.



---



## Roadmap



- **Ahora:** HF Spaces Docker (este folder = código fuente, sin cambios entre dev local y prod Space)

- **Futuro:** migración a AWS App Runner. Ver doc 33 §13. El Dockerfile actual sirve igual sin cambios.