tde-es-en-lite

Motor de decisiones tipadas (choice / score / noul) sobre un encoder bidireccional int8 recortado a español e inglés. No genera texto: elige entre opciones que le das, puntúa una rúbrica o estima si una proposición se desprende de un texto, y siempre devuelve números (probabilidades), con la opción de abstenerse. Corre en CPU, con un solo hilo, sin GPU y sin Python en runtime, mediante el binario nativo tde (Rust).

Código, binario y herramientas: repositorio typed-decision-engine.

Las plataformas distintas de macOS Intel solo se verificaron a nivel de compilación (ver "Plataformas").

Qué es

  • Backbone: intfloat/multilingual-e5-small (MIT, verificado en la metadata del repo de Hugging Face), congelado, con el vocabulario recortado de 250.002 a 54.358 tokens (es/en) y cuantizado a int8. El recorte es una selección de filas de la matriz de embeddings original, sin reentrenar el backbone.
  • Tokenizador propio en Rust (Unigram compacto con normalizador Precompiled): 4933/4933 casos idénticos a la implementación de referencia de Hugging Face (4900 frases reales es/en más ~40 casos hostiles).
  • Dos modos:
    • Abierto (tde ask): sin schema. Las opciones o la proposición llegan en cada llamada. choice/score puntúan con el coseno (escala 80) entre el estado y un prototipo por opción: el embedding de la etiqueta o, si das ejemplos, la media normalizada de la etiqueta y sus ejemplos (sin entrenar). claim estima si una proposición libre se desprende del texto con una cabeza de pares NLI (universal.bin).
    • Schema (tde decide): preguntas fijas declaradas en JSON, con cabezas entrenadas por pregunta (heads.bin). Se incluye de ejemplo schemas/support.json (tickets de soporte).

Uso en 3 comandos

Requiere el binario tde (cargo build --release) y Rust 1.82+ para compilarlo.

# 1. Descargar los pesos (reemplaza por el repo real una vez publicado)
tools/fetch_model.sh <usuario>/<repo>          # -> models/<repo>/ (usa luego --model models/<repo>;
                                               # el defecto del binario es models/es-en-lite)

# 2. Bajar ONNX Runtime 1.20.1 para tu plataforma
tools/fetch_ort.sh

# 3. Preguntar
cargo run --release -- ask --model models/<repo> \
  --question "¿De qué trata?" --options 'deportes|política|tecnología' \
  "El equipo ganó la final con un gol en el último minuto"
cargo run --release -- decide support --model models/<repo> \
  "Me cobraron dos veces y quiero el reembolso"

tde ask --claim 'proposición' <texto> estima si la proposición se desprende del texto. Las opciones admiten ejemplos: --options 'a=ej1;ej2|b=ej3|c'.

Arquitectura

estado ──▶ encoder int8 (12 capas, H=384) ──▶ z ∈ ℝ³⁸⁴   (1 forward por consulta)
opciones / preguntas ──▶ embeddings (cacheados por texto)
                                  │
                abierto: choice/score = 80·cos(z, prototipo); claim = cabeza NLI de pares sobre [z, q, z⊙q, |z−q|]
                schema:  proyección por pregunta (heads.bin) + calibración (T, vector scaling)

El costo por opción es un producto punto de 384 dimensiones: el número de opciones no compite con el estado por una ventana de tokens. La abstención (abstain) se decide por margen top-2 y entropía.

Resultados

tarea n motor propio 0 ej. Laya 0 ej. respondidas (cobertura) 0 ej.
NLI inglés sí/no (MNLI) 150 0.80 0.78 0.85 (79%)
NLI español sí/no (XNLI) 150 0.80 0.65 0.86 (84%)
afirmación verdadera, 3 opciones 150 0.85 0.69 0.85 (95%)
intención MASSIVE en (60) 150 0.39 0.42 0.62 (52%)
intención MASSIVE es (60) 150 0.35 0.32 0.53 (49%)
intención HWU64 (64) 150 0.53 0.47 0.71 (61%)
intención Banking77 (77) 150 0.58 0.38 0.68 (78%)
intención CLINC150 (150) 126 0.67 no soportado 0.80 (72%)
escenario MASSIVE en (18) 150 0.44 0.57 0.60 (68%)
escenario MASSIVE es (18) 150 0.47 0.42 0.70 (53%)
emoción GoEmotions (28) 150 0.14 0.38 0.35 (31%)
tema AG News (4) 150 0.57 0.96 0.63 (77%)

Calidad con cabezas entrenadas por schema (tickets de soporte, es/en)

90 casos escritos a mano para este proyecto, 67 de entrenamiento y 23 de validación. Por el binario desplegable (tde eval): accuracy 0.836, accuracy de las respondidas 0.993, cobertura 0.84, ECE 0.031. Esas cifras incluyen los 67 casos de entrenamiento; las cifras de validación (23 casos, por pregunta) están en docs/entrenamiento.md del repositorio y con ese n las diferencias entre preguntas no son estadísticamente significativas. No predicen rendimiento en otro dominio.

Cómo leer la tabla de arriba

  • Mismas filas para todos (bench/open/sample*.jsonl); el motor propio se mide con el binario desplegable (tde open-eval) y Laya con su paquete Python en CPU, sin calibrar. Las columnas "ej." dan 5 o 10 ejemplos de entrenamiento por opción (sin entrenar nada); donde no hay conjunto de entrenamiento (AG News, NLI) no aplican.
  • La columna de motor propio cuenta la abstención como error: es lo comparable con Laya, que siempre responde. La última columna muestra la accuracy de lo que contesta con la política de abstención por defecto y su cobertura.
  • Ganar o perder depende de la tarea: el motor propio es mejor o similar en NLI y en intenciones con muchas opciones (Laya gana por 3 puntos en MASSIVE-en, dentro del ruido de 150 filas) y Laya, de 421M de parámetros, es claramente mejor en escenarios en inglés, emociones y temas (AG News, GoEmotions).
  • El tamaño de muestra es de 150 filas por tarea: diferencias de pocos puntos no son significativas.

Recursos

Medido en i9-9880H, macOS Intel, 1 hilo, sin GPU.

es-en-lite (este paquete) antes (sin recortar) Laya (CPU, misma máquina)
encoder int8 en disco 43.0 MB 118 MB 223 MB
cabezas del schema (heads.bin) 7.1 MB 7.1 MB n/d
tokenizador en disco 1.3 MB (tokenizer.bin) 5.8 MB n/d
tokenizador en RAM ~2 MB (medido +0,2 a +2 MB de RSS) 399 MB (crate tokenizers) n/d
RSS ~128 MB 707 MB n/d
p50 por forward ~10.7 ms 14.7 ms 279 ms por llamada

Jev es una API de pago y no se pudo correr; sus 236 a 588 ms son cifras publicadas, no medidas aquí. La cifra de Laya con GPU (33 ms) no es comparable.

Plataformas

Se verificó únicamente que el código compila (cargo check, vía tools/check_portability.sh) para cinco destinos: Linux x64, Linux arm64, macOS Intel, macOS Apple Silicon y Windows x64. No se ejecutó en ninguna distinta de macOS Intel. Hay una matriz de CI (.github/workflows/ci.yml) que no se ha ejecutado. ONNX Runtime se carga en runtime (load-dynamic; 1.20.1, la última versión con binarios para macOS Intel).

Limitaciones

  • --claim es poco fiable con afirmaciones verdaderas cortas. La cabeza NLI se entrenó con hipótesis de MNLI (oraciones completas): "El texto habla de un animal" sobre "El perro ladró toda la noche" da P(true) = 0.13. Con afirmaciones falsas acierta. Con texto vacío o mayormente en alfabetos no latinos el motor abierto se abstiene. Detalle en docs/problemas_conocidos.md.
  • No genera texto. Solo elige entre opciones dadas, puntúa una rúbrica o estima una proposición. No inventa opciones.
  • Zero-shot en tareas nuevas: ~0.5. Es el orden de magnitud de las tareas de intención de la tabla; mejora con ejemplos por opción pero no es un modelo de uso general. Es peor que Laya en temas y emociones.
  • Solo español e inglés. Los alfabetos no latinos (CJK, árabe, cirílico...) pasan a <unk>. En un held-out es/en (MASSIVE test, XNLI-es test, MNLI) el entre el 0.04 y el 0.08 % de los tokens usa un id podado.
  • Las cabezas entrenadas por schema no generalizan fuera del schema. El dataset es pequeño, sintético y escrito a mano.
  • No se publica ninguna cabeza aprendida para choice/score. Se probó una cabeza universal entrenada con intenciones y escenarios: mejoró las familias vistas y empeoró en tareas no vistas (CLINC 0.32 a 0.49 frente a 0.60 del coseno), es decir, aprendió las etiquetas en vez de generalizar. Usar la cabeza NLI como scorer de opciones fue inestable entre entrenamientos (0.50 en una corrida, 0.41 en otra). Por eso choice/score usan el coseno y universal.bin solo se aplica a claim.
  • No se hizo fine-tuning de Laya con los mismos datos que las cabezas por schema del motor propio.
  • Cualquier cambio de tokenización o de encoder invalida los embeddings cacheados y obliga a reentrenar las cabezas.
  • Confianza y abstención: la abstención por margen y entropía no elimina el fallo "confidente y equivocado"; solo se midió en los 90 casos de soporte.

Licencias y atribuciones

  • Pesos de este paquete: MIT (LICENSE), con el aviso de copyright del modelo base intfloat/multilingual-e5-small (MIT, Microsoft Corporation) y las atribuciones del entrenamiento. El código del repositorio typed-decision-engine es Apache-2.0.
  • Entrenamiento de la cabeza NLI (universal.bin): MultiNLI (Williams, Nangia y Bowman, NAACL 2018) sin el género fiction. Las cabezas del schema de ejemplo (heads.bin) se entrenaron con 90 casos escritos por el autor del proyecto.
  • Selección de vocabulario: frecuencias de tokens sobre MASSIVE, MNLI y una muestra de Wikipedia en español; solo se conserva una lista de ids, no texto.
  • Solo evaluación (no entran a ningún peso): MASSIVE, CLINC150, Banking77, HWU64, GoEmotions, XNLI y AG News. XNLI (CC BY-NC) y AG News (uso no comercial declarado) se usan únicamente para medir.
  • Verificación de cada licencia contra su fuente en docs/licencias_verificacion.md. No es asesoría legal; el origen del aviso de copyright de e5 (repositorio microsoft/unilm) y la licencia original del OANC están indicados allí como verificaciones parciales.

Cómo reproducir

tools/fetch_ort.sh                                     # ONNX Runtime
tools/.venv/bin/python tools/export_model.py           # backbone -> ONNX int8
tools/.venv/bin/python tools/prune_vocab.py            # recorte de vocabulario es/en
tools/.venv/bin/python tools/build_tokenizer.py        # tokenizador compacto
tools/.venv/bin/python tools/tok_reference.py          # referencia HF para comparar tokenización
tools/.venv/bin/python tools/init_heads.py             # cabezas iniciales
cargo run --release -- precompile                      # embeddings de instrucciones/opciones
tools/.venv/bin/python tools/train_heads.py            # cabezas por pregunta (schema)
tools/.venv/bin/python tools/train_claim_head.py        # cabeza NLI de pares
cargo run --release -- eval --data <jsonl>             # evaluación por el binario real
cargo run --release -- open-eval --data <jsonl>       # evaluación en tareas abiertas
cargo run --release -- bench                           # latencia, RSS, norma
tools/check_portability.sh                             # cargo check en 5 destinos
python tools/package_hf.py && python tools/verify_package.py dist/tde-es-en-lite

Los argumentos concretos de cada script están en su cabecera; no todos los comandos anteriores se re-ejecutaron para esta tarjeta.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for jul879n/tde-es-en-lite

Quantized
(300)
this model

Dataset used to train jul879n/tde-es-en-lite