# Formatos de dataset para afinar un modelo: chat, Alpaca, ShareGPT y cuál te toca

**Respuesta corta.** Casi todo el ecosistema come JSONL con una de cuatro formas:
un campo `text` para preentrenamiento continuado, un campo `messages` con roles
para chat (TRL, Unsloth y el afinado de OpenAI), los campos `prompt` y
`completion`, o los tres campos `instruction`, `input` y `output` del formato
Alpaca que esperan Axolotl, LLaMA-Factory y Unsloth. Elige según el entrenador
que vayas a usar, no según lo que parezca más completo: un archivo con los
nombres de campo equivocados falla en la validación y el mensaje rara vez dice
cuál es el campo que sobra.

---

## La tabla que resuelve el 90 % de los casos

| Forma | Campos | Para qué sirve | Quién la come |
|---|---|---|---|
| Texto | `text` | Seguir preentrenando con tu material | TRL |
| Conversación | `messages[{role, content}]` | Afinado supervisado de chat | TRL, Unsloth, OpenAI |
| Instrucción | `prompt`, `completion` | Afinado de completado | TRL |
| Alpaca | `instruction`, `input`, `output` | Afinado por instrucciones | Axolotl, LLaMA-Factory, Unsloth |
| ShareGPT | `conversations[{from, value}]` | Conjuntos públicos de chat | Muchos entrenadores |
| Preferencias | `prompt`, `chosen`, `rejected` | DPO y similares | TRL |

Fuente de la fila de TRL: su página de
[dataset formats](https://huggingface.co/docs/trl/en/dataset_formats), que los
documenta como conversational y standard.

## Los detalles que rompen cosas

Estos no salen en los tutoriales y cuestan una tarde cada uno.

### PRMTrainer usa plurales

Donde el resto usa `completion` y `label`, `PRMTrainer` espera `completions` y
`labels`. Un archivo válido para el resto de TRL falla aquí sin explicación
clara.

### El DPO de OpenAI no usa los nombres de TRL

Es el error más caro de la lista, porque parece que ya lo tienes resuelto. TRL
usa `prompt`, `chosen` y `rejected`. OpenAI usa `input` —un objeto que envuelve
`messages`—, `preferred_output` y `non_preferred_output`, y además solo admite un
turno. Un exportador que asuma TRL produce archivos que no pasan la validación de
OpenAI.

### OpenAI admite peso por mensaje

En afinado supervisado puedes poner `weight: 0` en un mensaje de asistente para
que no se entrene sobre él. Útil cuando el ejemplo contiene una respuesta
correcta y otra que quieres conservar como contexto pero no imitar.

### LLaMA-Factory necesita una entrada extra

No basta con el JSONL: hay que registrar el conjunto en `dataset_info.json` con
sus `columns` y sus `tags`. Si el entrenamiento arranca y no aprende nada,
revisa ahí antes que en el modelo.

### ShareGPT está deprecado como opción, no como formato

En Axolotl, `type: sharegpt` está deprecado. Hoy se declara
`type: chat_template` con `message_property_mappings`. El formato de datos sigue
siendo perfectamente usable; lo que cambió es cómo se le dice al entrenador que
lo interprete.

### Anthropic no tiene formato propio documentado

Que hayamos podido verificar, no hay un formato público de afinado de Anthropic.
El único oficial legible es el de AWS Bedrock para Claude 3 Haiku:
`{"system": "...", "messages": [...]}`, con un mínimo de 32 registros.

## Cuál elegir, en tres preguntas

**¿Quieres enseñarle conocimiento nuevo?** Entonces probablemente no quieras
afinar. El afinado enseña *forma*: tono, estructura, formato de salida,
vocabulario del dominio. Para *hechos* que cambian, un RAG es más barato, más
actualizable y más auditable. Si igual vas a afinar, usa `text` para
preentrenamiento continuado.

**¿Quieres que responda como tú responderías?** Formato conversación
(`messages`). Es el más portable: lo entienden TRL, Unsloth y el afinado de
OpenAI con el mismo archivo.

**¿Vas a usar Axolotl, LLaMA-Factory o Unsloth con recetas de la comunidad?**
Alpaca, porque es lo que esperan sus configuraciones de ejemplo y te ahorra
traducir.

## Para RAG, ninguno de los anteriores

Si el destino no es un entrenador sino una base vectorial, los formatos son
otros:

| Destino | Forma |
|---|---|
| LangChain | `Document` con `page_content` y `metadata` |
| LlamaIndex | `TextNode` con `id_`, `text` y `metadata` |
| Pinecone, Qdrant, pgvector, Chroma | `id`, texto y metadatos |

Un detalle que ahorra dolores: que el `id` sea **estable y derivado del
contenido**. Así, reindexar actualiza el nodo en vez de duplicarlo, y puedes
regenerar el índice sin limpiarlo antes.

## Lo que se puede generar sin llamar a un modelo

Hay un formato más que casi nadie produce desde documentos y que no necesita un
modelo: los pares de **recompensa verificable** para aprendizaje por refuerzo.

DeepSeek-R1 ([arXiv:2501.12948](https://arxiv.org/html/2501.12948v1), §2.2.2)
explica por qué importa:

> «for math problems with deterministic results, the model is required to provide
> the final answer in a specified format […] enabling reliable rule-based
> verification of correctness […] We **do not apply the outcome or process neural
> reward model** […] because we find that the neural reward model may suffer from
> **reward hacking**.»

El conjunto de referencia de AI2 para esto tiene `messages`, `ground_truth` y
`dataset`. Y `GRPOTrainer` solo exige la columna `prompt`: cualquier columna
extra llega a la función de recompensa como argumento con nombre.

Conclusión práctica: **un dataset de RLVR es JSONL con `prompt` y
`ground_truth`**, y una tabla de un PDF ya es un conjunto de hechos con respuesta
única. «¿Cuánto costó el examen de laboratorio?» tiene una sola respuesta, está
impresa en la página, y comprobarla es comparar dos cadenas.

Dos reglas de calidad que hay que aplicar al generarlos, o el dataset castiga al
modelo por acertar:

- Si una clave de fila se repite, esa pregunta no se emite: tendría dos
  respuestas.
- Si hay empate en el máximo o el mínimo de una columna, tampoco.

## Cómo exportarlo

En el navegador: [PDF a datos de IA](/es/pdf-a-jsonl/) tiene los ocho formatos en
un desplegable y te enseña las primeras líneas antes de descargar.

En terminal:

```bash
npx sirdas dataset docs/*.pdf --format chat --split --hf -d dataset/
npx sirdas dataset docs/*.pdf --format alpaca -d ds/
npx sirdas rl facturas/*.pdf --lang es -o rl.jsonl
npx sirdas rl --reward-fn > reward.py
```

Con `--hf` salen `train.jsonl`, `validation.jsonl`, `test.jsonl` y la tarjeta de
Hugging Face. Con `--reward-fn`, la función de recompensa en Python lista para
pegar en `GRPOTrainer`, con el mismo criterio de comparación que se usó al
generar los pares.
