# 06 — Texto natural a tags Danbooru

Estado: **visión, nada implementado.** Es lo segundo que vamos a querer
experimentar: escribir prompts o líneas creativas y traducirlos a tags.

## La idea

Escribir una frase normal ("una chica de pie en la playa, bañada por la luz del
atardecer") y obtener una línea de tags Danbooru válida, lista para pegar en
un prompt. Para probar cosas creative sin pelearse con la sintaxis.

## Cómo lo resuelve WaifuStudio (y qué copiamos)

El mecanismo tiene **cuatro pasos**, y lo importante es el último:

1. El modelo de lenguaje escribe libremente en lenguaje natural.
2. Se separa en tags.
3. **Cada tag se valida contra el catálogo Danbooru.**
4. Los inventados **se descartan y se listan** en la respuesta, como `dropped`.
   Los alias se resuelven al canónico.

> **Lo que copiamos es el paso 4: no confiar en la salida del modelo, pasarla
> por el catálogo después.** El LLM puede inventar tags que el modelo de
> difusión nunca ha visto; en lugar de adivinar si funcionan, se tiran.

## Por qué aquí no hace falta (aún)

Nuestro WD14 **ya emite tags del vocabulario Danbooru por construcción**: viene
de un clasificador entrenado sobre ese vocabulario, así que no hay nada
inventado que validar. El problema no se nos da.

Donde **sí** nos serviría:

- Escribir una **línea creativa suelta** (un ambiente, un accesorio, una
  Lighting) y convertirla en tags válidos sin saber si existen.
- Cualquier prompt que escribamos **a mano**, que es donde más se nos escapan
  tags inventados.

## Los catálogos: el nuestro ya es mejor

| | WaifuStudio | Ours (`Archivos/Danbooru tags.csv`) |
|---|---|---|
| Fichero | 6,9 MB | 4,6 MB |
| Tags | 91.357 | **192.000** |
| Columnas | `category` (legible), `posts` (frecuencia), `aliases` | `tag`, `type` (numérico), `count`, `aliases` |
| Capa curada | **3.249 tags con ranking** | no |

**No hay que adoptar nada.** El nuestro tiene el doble de tags y las mismas
funciones útiles. Lo único que nos falta y **sí vale la pena copiar**:

- La **capa curada de 3.249 tags con ranking**: pocos tags para *ofrecer*, todos
  para *validar*. Es la idea de separar "lo que elige una persona" de "lo que
  acepta el sistema". Es barata: basta con quedarse con los de mayor `count`.

> Ojo con la cabecera: nuestro CSV **sí la tiene** (`tag,type,count,aliases`).
> El de e621 merged **no**, así que parseándolo con `DictReader` te comes una
> fila de datos como cabecera.

## Nodos ComfyUI (si se implementa aquí)

El repo de WaifuStudio trae su propio cliente de LLM local: **Qwen3.5-9B en
CPU**, 0 VRAM, arrancado y parado por la app. Esa es la idea útil: **un LLM en
CPU no compite con la GPU por la VRAM**. Como el nuestro noocabría VRAM para
vídeo, no hay conflicto.

Alternativa que ya tenemos: la carpeta `_legacy/Scripts/DeepSeek/`, archivada
porque el proveedor retiró el modelo. **La lección sigue viva**: un LLM local
propio evita depender de un servicio de pago que puede desaparecer.

## Advertencia de calidad

La conversión texto→tags es útil para **explorar**, no para el prompt final.
Un LLM normal conoce Danbooru de oídas y producirá cosas como
`beautiful_shiny_hair` que pasan el filtro solo porque el filtro no es
estricto, o cosas que son válidas pero no lo que queríamos.

Regla que nos sirve: **validar siempre contra el catálogo, y cuando algo se
dropee, mirarlo.** Un tag inventado que sobreviva al filtro no es un acierto,
es un falso positivo.