Empezar
EmoParse se instala una vez y se usa escribiendo comandos en la consola de la computadora. Los tutoriales del repositorio indican exactamente qué escribir en cada paso. Esta página describe qué hace cada cosa.
La consola, también llamada terminal o línea de comandos, es una ventana donde se le dan órdenes escritas a la computadora en lugar de hacer clic. Viene incluida en Windows, macOS y Linux. Todo lo que sigue son líneas para escribir ahí y apretar Enter.
1Qué hace falta
- Python 3.11 o posterior
- El lenguaje en el que está escrito EmoParse. Se descarga del sitio oficial y se instala como cualquier otro programa.
- Git
- Un programa para descargar y mantener actualizado el código desde el repositorio.
- Alrededor de 20 GB de disco
- Los modelos de lenguaje son archivos grandes y se guardan en la computadora.
- Una placa de video, recomendada
- La placa de video es el componente que hace muchos cálculos en paralelo. Los modelos de lenguaje están hechos para aprovecharla, así que con placa el análisis va bastante más rápido. Sin placa el programa funciona igual, con el procesador común, pero un corpus grande puede tardar mucho.1
2Instalar
Tres pasos: traer el código, armarle un espacio propio, e instalarlo.
# 1. Traer el código
git clone https://github.com/alexdcolman/EmoParse.git
cd EmoParse
# 2. Crear un espacio aislado para las bibliotecas del programa
python -m venv .venv
source .venv/bin/activate # Linux y macOS
# .venv\Scripts\activate # Windows
# 3. Instalar
pip install -e ".[llamacpp,ui,scraping]"
El espacio aislado del segundo paso evita que las bibliotecas de EmoParse interfieran con las de otros programas de la misma computadora. Hay que activarlo cada vez que se abra una consola nueva.
Lo que va entre corchetes en el tercer paso son los agregados opcionales. Cada uno suma una capacidad y se instala solo si hace falta.
| Agregado | Para qué |
|---|---|
llamacpp | Correr modelos de lenguaje localmente. |
lmstudio | Usar modelos a través de LM Studio, mediante su API compatible con OpenAI. |
openai / anthropic | Usar APIs remotas de forma explícita por stage. No requieren un extra de Python. |
ui | El tablero de exploración. |
scraping | Bajar discursos presidenciales y artículos periodísticos de sitios web. |
nlp | Análisis gramatical, que usa la etapa de modalidad referencial. |
bluesky | Adquirir posts de Bluesky. Mastodon no requiere agregado. |
techno | Lectura de emojis compuestos de varios símbolos. |
network | Análisis de redes entre cuentas. |
embeddings | Agrupamiento de textos por parecido de contenido. Pesado; opcional. |
all | Todo lo anterior. |
El backend llama_server usa el cliente HTTP incluido en la instalación base; no
necesita un agregado de Python. El ejecutable llama-server se obtiene con llama.cpp.
Una compilación CUDA mínima puede hacerse fuera del repositorio de EmoParse:
git clone https://github.com/ggml-org/llama.cpp.git ~/tools/llama.cpp
cd ~/tools/llama.cpp
cmake -B build -DGGML_CUDA=ON -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release --target llama-server -j "$(nproc)"
./build/bin/llama-server --version
Si el alias del modelo declara también la ruta del GGUF, EmoParse puede mostrar el comando
efectivo, iniciarlo en primer plano y comprobar después la salud y los slots observables del
servidor. Si el binario no está en PATH, se puede pasar su ruta con
--binary.
# Revisar sin iniciar nada
emoparse server --config config.yaml --model mi-modelo-server --dry-run
# Iniciar en primer plano
emoparse server --config config.yaml --model mi-modelo-server
# Comprobar desde otra terminal
emoparse server --config config.yaml --model mi-modelo-server --check
server_parallel declara los slots del servidor y
pipeline.parallel la concurrencia solicitada por EmoParse. En modelos MoE,
cpu_moe o n_cpu_moe permiten declarar la descarga de expertos a CPU
para llama_server; no se aplican al backend en proceso llama_cpp.
cache_reuse sólo debe activarse cuando el contexto del modelo lo admite; si
llama.cpp informa que lo desactiva al iniciar, conviene declararlo en 0.
APIs remotas opcionales
EmoParse también puede ejecutar una stage con OpenAI o Anthropic. Es una opción explícita: el routing local no cambia y sólo los prompts de las stages asignadas a un alias remoto se envían al proveedor. Las claves se leen desde variables de entorno y se omiten del snapshot persistido del run.
export OPENAI_API_KEY="..."
export ANTHROPIC_API_KEY="..."
# En config.yaml
models:
mi-openai:
backend: openai
model_id: gpt-model-id
api_key_env: OPENAI_API_KEY
mi-anthropic:
backend: anthropic
model_id: claude-model-id
api_key_env: ANTHROPIC_API_KEY
Los campos opcionales precio_input y precio_output
expresan USD por millón de tokens y permiten guardar un costo estimado en las métricas. No hay
precios predefinidos porque cambian según proveedor y modelo. El cache de EmoParse se mantiene y
--budget-tokens sigue contando únicamente tokens nuevos.
La etapa de modalidad referencial necesita además un modelo gramatical del español, que se baja una vez:
pip install -e ".[nlp]"
python -m spacy download es_core_news_md
Instalar dentro de un contenedor
También se puede aislar la instalación con Docker. El perfil cpu sirve para el tablero y para backends accesibles por API; el perfil cuda agrega llama-cpp-python compilado con CUDA para modelos locales. Ambos se construyen desde el repositorio y mantienen los modelos, corpus, configuraciones y bases fuera de la imagen.
docker build -f docker/Dockerfile.cpu -t emoparse:cpu .
docker build -f docker/Dockerfile.cuda -t emoparse:cuda .
# Comprobar la imagen sin cargar un modelo
python scripts/container_smoke.py --profile cpu --image emoparse:cpu --no-build
python scripts/container_smoke.py --profile cuda --image emoparse:cuda --no-build
Las etiquetas se crean en la computadora donde se hace el build. Los modelos GGUF se montan desde afuera, por ejemplo sobre /models; los resultados persistentes se escriben en un directorio montado sobre /runs. El perfil CUDA requiere NVIDIA Container Toolkit y acceso explícito a la GPU con --gpus all; las bibliotecas del driver se inyectan desde el host al iniciar el contenedor.
3Los modelos
EmoParse no incluye los modelos de lenguaje: se descargan por separado y se guardan en la
carpeta models/. Vienen en un formato comprimido que permite usarlos en computadoras
comunes, a costa de una pérdida mínima de precisión.2
| Modelo | Tamaño | Para qué etapas |
|---|---|---|
qwen3-14b | ~9 GB | Detección de emociones, actores, situación de habla, caracterización. |
qwen3-30b-a3b | ~18 GB | Resumen de textos largos. |
phi-4-mini-instruct | ~2 GB | Tareas de ficha simple, como el tipo de discurso. |
Un modelo distinto por etapa es la configuración habitual: las tareas de ficha breve no
justifican un modelo grande. Con el backend llama_cpp, el programa carga y descarga los
modelos dentro del mismo proceso a medida que cambia de etapa. También puede conectarse a un
servidor local llama-server o a LM Studio mediante una API compatible con OpenAI; en
los tres casos las respuestas mantienen el mismo contrato estructurado.
4Configurar
La configuración vive en un archivo de texto que se copia del ejemplo incluido y se edita. Ahí se indican dónde están los modelos, qué modelo usa cada etapa, de a cuántas unidades se procesa por vez y dónde se guardan los resultados.
cp config.example.yaml config.yaml
5Un primer análisis
La entrada mínima es una planilla con dos columnas: un identificador único por texto y el texto en sí. El género elegido determina cómo se segmenta y qué contexto acompaña cada unidad.
Discursos presidenciales
# Bajar discursos de Casa Rosada
emoparse scrape --source casarosada \
--output data/discursos.csv \
--from 2024-01-01 --to 2024-12-31
# Correr el análisis
emoparse run \
--config config.yaml \
--input data/discursos.csv \
--genre discurso_presidencial \
--run-id mi_primer_analisis
Artículos periodísticos
# Bajar artículos de Página/12
emoparse scrape --source pagina12 \
--max 24 \
--output data/articulos.csv
# Correr el análisis por párrafos
emoparse run \
--config config.yaml \
--input data/articulos.csv \
--genre articulo_periodistico \
--run-id articulos01
Corpus tabulares propios
Un CSV no tiene que usar de antemano los mismos nombres de columnas que EmoParse. Antes de
analizarlo, doctor puede revisar codificación, delimitador, fila de encabezado,
identificadores, contenido, fechas y restos de HTML sin modificar el archivo.
ingest-map propone después un YAML editable de correspondencia de columnas; solo ese
archivo, cuando se pasa explícitamente a run, se usa para la ingesta.
# Diagnosticar sin escribir el corpus
emoparse doctor --input corpus_externo.csv --genre discurso_presidencial
# Crear una propuesta y revisarla a mano
emoparse ingest-map --input corpus_externo.csv --out mapping.yaml
# Verificar el mapping editado
emoparse doctor --input corpus_externo.csv --mapping mapping.yaml
# Usarlo en la corrida
emoparse run --config config.yaml --input corpus_externo.csv \
--run-id corpus01 --mapping mapping.yaml
Las columnas que no forman parte de esa correspondencia se conservan como metadata del input. El archivo original no se reescribe.
El tutorial de discursos presidenciales y el tutorial de artículos periodísticos desarrollan ambos recorridos paso por paso.
# Ver cómo viene, desde otra consola
emoparse status --db runs/mi_primer_analisis.sqlite
# Abrir el tablero
emoparse app
Conviene correr por bloques y revisar cada resultado antes de seguir, en lugar de lanzar todo
de una vez. Las etapas se eligen con --stages:
emoparse run \
--config config.yaml \
--input data/discursos.csv \
--genre discurso_presidencial \
--run-id mi_primer_analisis \
--resume \
--stages summarizer,metadata,enunciation,actors,emotions,explode_emotions
También se puede acotar una corrida con un YAML sin modificar el corpus original. Los campos
del input se filtran al comienzo; los resultados de etapas anteriores se referencian con notación
punto, como metadata.tipo_discurso o
enunciation.enunciador.nombre, y empiezan a filtrar recién después de que la etapa
productora queda completa. Una ejecución posterior sin selector retoma lo que quedó afuera sin
repetir resultados persistidos.
emoparse run --config config.yaml --input data/discursos.csv \
--run-id prueba_acotada \
--select data/ejemplos/seleccion_payload_v070.yaml
El comando emoparse status distingue lo pendiente, lo no aplicable y lo excluido
por el selector en cada etapa.
Si la corrida debe respetar un techo de uso, --budget-tokens N fija un presupuesto
acumulado para esa base. Al alcanzarlo, el run queda pausado y se puede continuar con
--resume y un techo mayor; las respuestas recuperadas de cache no vuelven a sumar
tokens.
Cada análisis produce un archivo único en la carpeta runs/, con el nombre que se
le haya dado. Ese archivo contiene el texto de entrada, todos los resultados intermedios y las
versiones exactas de las instrucciones y las categorías que se usaron. Copiarlo a otra
computadora alcanza para reproducir la exploración completa.
6Un corpus de posts
Para posts de redes sociales, el corpus se adquiere primero y se analiza después, con la indicación del género. La adquisición admite Bluesky, Mastodon y la API oficial de X, además de importar dumps JSONL o CSV.
# 1. Adquirir
emoparse acquire --source bluesky --query "#tarifazo" --lang es \
--max 500 --out data/tarifazo.jsonl
# 2. Analizar
emoparse run --config config.yaml --genre tuit \
--input data/tarifazo.jsonl --run-id tarifazo01
# 3. Redes entre cuentas
emoparse network --db runs/tarifazo01.sqlite \
--flujo --similitud --export-dir exports/red
Los detalles del género, sus etapas propias y las opciones de adquisición están en Posts y redes y en el tutorial de tuits y discurso nativo digital.
7Los comandos
El programa se maneja con un puñado de comandos. Los tres que se usan casi siempre son
emoparse run, que corre el análisis; emoparse status, que informa qué
quedó pendiente y qué falló; y emoparse app, que abre el tablero. Los demás cubren
la adquisición de corpus, el análisis de redes, la validación y la exportación.
La lista completa, con todas las opciones de cada comando, está en
Comandos. Todos aceptan además --help, que imprime lo
mismo en la consola.
8Si algo falla
Se queda sin memoria al cargar el modelo
Hay tres salidas, de menor a mayor pérdida: reducir cuánto del modelo se carga en la placa de video, reducir el tamaño de texto que el modelo lee de una vez, o usar una versión más comprimida del mismo modelo.
Avisa que el texto excede el límite, pero el texto no parece largo
Puede ocurrir por dos razones. Una es que las instrucciones más el texto superen lo que el modelo admite de una vez. La otra es que el modelo no haya terminado de cerrar su respuesta dentro del límite de longitud fijado. El mensaje de error informa cuál de las dos fue. Las instrucciones de lectura se pueden acortar sin tocar el programa: están en archivos de texto aparte.
Algunas unidades salen sin ninguna emoción
Es un resultado legítimo si no hay emoción que detectar. Si ocurre de manera sistemática en unidades con emoción evidente, conviene revisar tres cosas: que la lista de categorías cubra ese tipo de emoción, que las indicaciones de lectura contemplen el caso, y que el modelo elegido no esté por debajo de lo que la tarea exige.
Los resultados no se repiten entre corridas
El manejo de la semilla de azar cambió entre versiones de la biblioteca que corre los modelos. Al actualizarla conviene volver a verificar que dos corridas idénticas den lo mismo.
El tablero no encuentra la corrida
El tablero busca en la carpeta indicada en la configuración. Conviene abrirlo desde el mismo directorio donde se corrió el análisis.
Los tres tutoriales del repositorio recorren casos completos paso a paso: discursos presidenciales, artículos periodísticos y posts de redes sociales.
Notas
- Para la configuración estándar hacen falta unos 12 GB de memoria en la placa de video. Los modelos más grandes requieren una placa mayor, o repartir el trabajo entre la placa y la memoria común, lo que funciona a menor velocidad. El análisis de redes y la adquisición de corpus no usan la placa en absoluto. ↩
- La compresión se llama cuantización: reduce la precisión numérica interna del modelo, con lo que ocupa menos espacio y corre más rápido. Las variantes recomendadas conservan la calidad de las respuestas para estas tareas. ↩