@ericrisco/rsc 0.1.38 → 0.1.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -2
- package/manifest.json +181 -3
- package/package.json +1 -1
- package/scripts/lib/domains.js +1 -0
- package/scripts/lib/recommend.js +6 -0
- package/skills/automation-strategy/SKILL.md +2 -2
- package/skills/automation-strategy/references/platform-selection-matrix.md +2 -2
- package/skills/deep-learning/SKILL.md +263 -0
- package/skills/deep-learning/evals/README.md +11 -0
- package/skills/deep-learning/evals/cases.yaml +48 -0
- package/skills/deep-learning/references/distributed.md +105 -0
- package/skills/deep-learning/references/training-recipes.md +135 -0
- package/skills/finetuning/SKILL.md +244 -0
- package/skills/finetuning/evals/README.md +13 -0
- package/skills/finetuning/evals/cases.yaml +50 -0
- package/skills/finetuning/references/hyperparameters-and-eval.md +74 -0
- package/skills/finetuning/references/methods.md +189 -0
- package/skills/harness/references/providers.yaml +38 -2
- package/skills/huggingface/SKILL.md +1 -1
- package/skills/machine-learning/SKILL.md +260 -0
- package/skills/machine-learning/evals/README.md +15 -0
- package/skills/machine-learning/evals/cases.yaml +54 -0
- package/skills/machine-learning/references/gbdt-and-tuning.md +83 -0
- package/skills/machine-learning/references/metrics-and-imbalance.md +82 -0
- package/skills/machine-learning/references/pipelines-and-cv.md +135 -0
- package/skills/n8n/SKILL.md +1 -1
- package/skills/nlp/SKILL.md +225 -0
- package/skills/nlp/evals/README.md +10 -0
- package/skills/nlp/evals/cases.yaml +45 -0
- package/skills/nlp/references/evaluation.md +107 -0
- package/skills/nlp/references/tokenization.md +95 -0
- package/skills/open-weights/SKILL.md +239 -0
- package/skills/open-weights/evals/README.md +14 -0
- package/skills/open-weights/evals/cases.yaml +42 -0
- package/skills/open-weights/references/licenses.md +123 -0
- package/skills/open-weights/references/model-families.md +83 -0
- package/skills/open-weights/references/sizing-and-quant.md +89 -0
- package/skills/roast-me/tools/adapters/__pycache__/__init__.cpython-312.pyc +0 -0
- package/skills/roast-me/tools/adapters/__pycache__/base.cpython-312.pyc +0 -0
- package/skills/roast-me/tools/adapters/__pycache__/claude.cpython-312.pyc +0 -0
- package/skills/roast-me/tools/adapters/__pycache__/codex.cpython-312.pyc +0 -0
- package/skills/roast-me/tools/adapters/__pycache__/gemini.cpython-312.pyc +0 -0
- package/skills/roast-me/tools/adapters/__pycache__/registry.cpython-312.pyc +0 -0
- package/skills/training-data/SKILL.md +226 -0
- package/skills/training-data/evals/README.md +13 -0
- package/skills/training-data/evals/cases.yaml +41 -0
- package/skills/training-data/references/formats.md +118 -0
- package/skills/training-data/references/synthesis-dedup-quality.md +134 -0
- package/skills/unsloth/SKILL.md +254 -0
- package/skills/unsloth/evals/README.md +10 -0
- package/skills/unsloth/evals/cases.yaml +42 -0
- package/skills/unsloth/references/export.md +75 -0
- package/skills/unsloth/references/grpo.md +91 -0
- package/skills/unsloth/references/masking-and-templates.md +91 -0
- package/skills/vllm/SKILL.md +235 -0
- package/skills/vllm/evals/README.md +9 -0
- package/skills/vllm/evals/cases.yaml +47 -0
- package/skills/vllm/references/flags-and-endpoints.md +105 -0
- package/skills/vllm/references/memory-and-throughput.md +78 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Open-weight model families — depth notes
|
|
2
|
+
|
|
3
|
+
**Every version and license line here is [verify the card] — authored against cards live mid-2026
|
|
4
|
+
(accessed 2026-07-18). Families and rough size ladders are durable; specific versions are not.**
|
|
5
|
+
Do not quote a license from this file into a product decision — open the model's `LICENSE`.
|
|
6
|
+
|
|
7
|
+
## Llama (Meta)
|
|
8
|
+
|
|
9
|
+
- **Sizes:** historically ~1B–70B dense; current line (Llama 4: Scout, Maverick) uses a
|
|
10
|
+
**mixture-of-experts** design with large total-param counts but a smaller active count per token.
|
|
11
|
+
- **Strengths:** huge ecosystem — the most fine-tunes, quants, tooling, and community docs of any
|
|
12
|
+
family. If "will it just work in my runtime" matters, Llama is the safe bet.
|
|
13
|
+
- **License:** **Meta Llama Community License — custom, NOT OSI-open.** Acceptable-Use Policy,
|
|
14
|
+
"Built with Llama" attribution, naming rules, and a **>700M-MAU** clause. Gated on the Hub. See
|
|
15
|
+
[licenses.md](licenses.md).
|
|
16
|
+
|
|
17
|
+
## Qwen (Alibaba)
|
|
18
|
+
|
|
19
|
+
- **Sizes:** a very wide ladder — sub-1B up to 200B+ (dense **and** MoE). Strong specialized lines:
|
|
20
|
+
**Qwen-Coder** (coding), **Qwen-VL** (vision), reasoning variants. Recent lines (Qwen3 / Qwen3.5 /
|
|
21
|
+
Qwen3.6) [verify].
|
|
22
|
+
- **Strengths:** excellent multilingual coverage, strong coding, a size for nearly every hardware
|
|
23
|
+
budget, generally permissive licensing.
|
|
24
|
+
- **License:** **mostly Apache-2.0 but per-size variance** — some sizes historically shipped under a
|
|
25
|
+
separate Qwen license. Check **each size's** card; never generalize "Qwen = Apache" to the family.
|
|
26
|
+
|
|
27
|
+
## Mistral / Mixtral (Mistral AI)
|
|
28
|
+
|
|
29
|
+
- **Sizes:** 7B dense (Mistral 7B), MoE (Mixtral 8x7B / 8x22B), and named tiers (Small/Large/Nemo).
|
|
30
|
+
- **Strengths:** efficient, strong for their size; Mixtral popularized accessible MoE.
|
|
31
|
+
- **License:** open models **Apache-2.0**; but **Codestral (original, code model) = MNPL
|
|
32
|
+
non-production** — free to eval, not to ship commercially. **Codestral 2** was relicensed
|
|
33
|
+
Apache-2.0 (Apr 2026) [verify]. Some newer models use a "Modified MIT" with a revenue-threshold
|
|
34
|
+
commercial clause. Per-model check required — see [licenses.md](licenses.md).
|
|
35
|
+
|
|
36
|
+
## Gemma (Google)
|
|
37
|
+
|
|
38
|
+
- **Sizes:** ~1B–~27B, plus specialized siblings: **PaliGemma** (vision-language), **CodeGemma**,
|
|
39
|
+
**ShieldGemma** (safety), **RecurrentGemma**, EmbeddingGemma, DataGemma.
|
|
40
|
+
- **Strengths:** strong small-model quality, good multilingual, tight integration with Google tooling.
|
|
41
|
+
- **License:** **Gemma 1–3 = custom Gemma Terms of Use + Prohibited Use Policy** (NOT Apache), with
|
|
42
|
+
a downstream pass-through duty. **Gemma 4** reportedly moved to **Apache-2.0** (confirmed on
|
|
43
|
+
ai.google.dev/gemma/terms, 2026-07-18) — verify the version you use. See [licenses.md](licenses.md).
|
|
44
|
+
|
|
45
|
+
## DeepSeek
|
|
46
|
+
|
|
47
|
+
- **Sizes:** very large MoE base/chat (V3-class, hundreds of B total), **R1** reasoning models, plus
|
|
48
|
+
**distills** into smaller Llama/Qwen backbones (handy for consumer hardware).
|
|
49
|
+
- **Strengths:** frontier-class reasoning and coding at open-weight cost; distills bring much of the
|
|
50
|
+
quality to small sizes.
|
|
51
|
+
- **License:** **per-model split.** Code repos MIT; **DeepSeek-R1 weights MIT**; original
|
|
52
|
+
**DeepSeek-V3 weights = custom DeepSeek License Agreement with OpenRAIL-style use restrictions**.
|
|
53
|
+
Newer point releases have moved toward MIT [verify]. Never assume "DeepSeek = MIT" — check the model.
|
|
54
|
+
|
|
55
|
+
## Phi (Microsoft)
|
|
56
|
+
|
|
57
|
+
- **Sizes:** small — ~3B to ~15B ("mini", reasoning, multimodal variants in the Phi-4 family).
|
|
58
|
+
- **Strengths:** punches above its weight on reasoning for the size (trained on curated/synthetic
|
|
59
|
+
data); great for edge and cost-sensitive deployments.
|
|
60
|
+
- **License:** **MIT** across the Phi-4 family [verify] — genuinely permissive, commercial-friendly.
|
|
61
|
+
|
|
62
|
+
## gpt-oss (OpenAI)
|
|
63
|
+
|
|
64
|
+
- **Sizes:** **gpt-oss-20b** and **gpt-oss-120b** — MoE, open *weights*. 120B runs on a single 80 GB
|
|
65
|
+
GPU; 20B targets ~16 GB.
|
|
66
|
+
- **Strengths:** OpenAI's first open-weight LLMs since GPT-2; strong reasoning/agentic/tool-use.
|
|
67
|
+
- **License:** **Apache-2.0** [verify] — permissive. Confirmed on OpenAI's own model-card page and
|
|
68
|
+
the Hugging Face repo (2026-07-18).
|
|
69
|
+
|
|
70
|
+
## Others worth knowing (check the card)
|
|
71
|
+
|
|
72
|
+
- **OLMo (AI2)** — *fully* open: weights **and** training data/code released. The pick when
|
|
73
|
+
reproducibility/provenance matters, not just weight availability.
|
|
74
|
+
- **SmolLM (HF)** — tiny, permissive, edge-friendly.
|
|
75
|
+
- **Falcon (TII)**, **Yi (01.AI)**, **Command / Command-R (Cohere)** — Command family often carries
|
|
76
|
+
more restrictive terms (research vs commercial split); verify carefully before shipping.
|
|
77
|
+
|
|
78
|
+
## The "will it work Monday" filter
|
|
79
|
+
|
|
80
|
+
Beyond quality, a family/size is only a real option if the **ecosystem** supports it: ready-made
|
|
81
|
+
GGUF/AWQ/GPTQ quants on the Hub, support in your runtime (llama.cpp/Ollama/vLLM/TGI), documented
|
|
82
|
+
chat template, and recent downloads. A brand-new model with no quants and no runtime support is a
|
|
83
|
+
research artifact — route the actual pull to `huggingface` and the run to `ollama`/`vllm`.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Size ↔ VRAM and quant formats — selection-time depth
|
|
2
|
+
|
|
3
|
+
This is the **"will it fit before I pick it"** estimate. The **operational** per-request KV-cache
|
|
4
|
+
sizing and runtime flags live in `ollama` (single box) and `vllm` (serving) — do not duplicate them
|
|
5
|
+
here. These numbers are rules of thumb for *choosing a size class*, not a per-model spec sheet;
|
|
6
|
+
confirm the real footprint with `ollama show` or the model card.
|
|
7
|
+
|
|
8
|
+
## The weights formula
|
|
9
|
+
|
|
10
|
+
```text
|
|
11
|
+
weights_GB ≈ params(B) × bytes_per_param
|
|
12
|
+
fp16 / bf16 → 2.0 (2 GB per 1B params)
|
|
13
|
+
int8 / 8-bit → ~1.0 (1 GB per 1B params)
|
|
14
|
+
4-bit → ~0.5–0.6 (≈ 0.6 GB per 1B params, conservative)
|
|
15
|
+
|
|
16
|
+
total_VRAM ≈ weights_GB + KV_cache + runtime_overhead
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The 4-bit rate is a round number: measured k-quant rates land near ~4.9 bits/weight for Q4_K_M
|
|
20
|
+
(~0.6 byte/param). Round **up** when budgeting so you don't OOM. **KV cache and overhead are extra**
|
|
21
|
+
and grow with context length — always leave a margin above the weights figure.
|
|
22
|
+
|
|
23
|
+
### Worked examples (weights only, fp16 unless noted)
|
|
24
|
+
|
|
25
|
+
| Model | Params | fp16 | 8-bit | 4-bit |
|
|
26
|
+
|---|---|---|---|---|
|
|
27
|
+
| Small | 3B | ~6 GB | ~3 GB | ~2 GB |
|
|
28
|
+
| Mid | 8B | ~16 GB | ~8 GB | ~5 GB |
|
|
29
|
+
| Large-consumer | 32B | ~64 GB | ~32 GB | ~20 GB |
|
|
30
|
+
| Big | 70B | **~140 GB** | ~70 GB | ~40 GB |
|
|
31
|
+
|
|
32
|
+
**The 70B lesson:** fp16 ~140 GB does not fit any single GPU on the market for most teams. Options:
|
|
33
|
+
(a) **quantize** to 4-bit (~40 GB → fits one 80 GB card), accepting some quality/throughput cost; or
|
|
34
|
+
(b) **tensor-parallel** across multiple GPUs (e.g. 2×80 GB) to keep full precision — a `vllm` job.
|
|
35
|
+
|
|
36
|
+
## What fits which hardware class
|
|
37
|
+
|
|
38
|
+
| Hardware | fp16 ceiling (weights) | Practical pick |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| 8 GB consumer GPU | ~3B | 7–8B @ 4-bit (~5 GB) + small context |
|
|
41
|
+
| 12 GB | ~5B | up to ~14B @ 4-bit |
|
|
42
|
+
| 16 GB | ~7B | 13–14B @ 4-bit; 7–8B @ 8-bit |
|
|
43
|
+
| 24 GB (3090/4090) | ~10B | ~32B @ 4-bit (~20 GB) |
|
|
44
|
+
| 48 GB (or 2×24) | ~22B | 70B @ 4-bit is tight; better on 80 GB |
|
|
45
|
+
| 80 GB (A100/H100) | ~34B | 70B @ 4-bit (~40 GB), or a big MoE (gpt-oss-120b) |
|
|
46
|
+
| 2×80 GB+ | 70B fp16 (~140 GB) via TP | full-precision large models |
|
|
47
|
+
| Apple unified (e.g. 64 GB) | shares with the whole OS | budget vs **total** unified memory, not a GPU number |
|
|
48
|
+
| CPU / edge | — | small GGUF (≤3B) at 4-bit; slow but runs |
|
|
49
|
+
|
|
50
|
+
## MoE: total vs active params
|
|
51
|
+
|
|
52
|
+
Mixture-of-experts models (Mixtral, gpt-oss, Llama 4, big Qwen/DeepSeek) route each token through a
|
|
53
|
+
**subset** of experts. So a "120B" MoE might activate only ~5B params per token (fast inference) —
|
|
54
|
+
**but you still need VRAM to hold all experts.** Budget against **total** params for memory and
|
|
55
|
+
against **active** params for the speed intuition. Don't size a 120B MoE as if it were a 5B dense.
|
|
56
|
+
|
|
57
|
+
## Quant formats — pick by runtime
|
|
58
|
+
|
|
59
|
+
| Format | Runtime | Notes |
|
|
60
|
+
|---|---|---|
|
|
61
|
+
| **GGUF** | llama.cpp, Ollama, LM Studio | The local default. CPU + Apple Silicon + single GPU. Self-contained files with quant in the name. |
|
|
62
|
+
| **AWQ** | vLLM, TGI, transformers | Activation-aware weight quant; strong 4-bit quality for GPU serving. |
|
|
63
|
+
| **GPTQ** | vLLM, TGI, transformers | Older post-training quant; very widely available 4-bit. |
|
|
64
|
+
| **bitsandbytes (NF4/int8)** | transformers | Load-time quantization — quick for experiments and QLoRA fine-tuning. |
|
|
65
|
+
| **EXL2** | ExLlamaV2 | Variable bit-rate; good on consumer GPUs, flexible size/quality. |
|
|
66
|
+
|
|
67
|
+
Rule: **local/Mac/CPU → GGUF**; **GPU serving → AWQ or GPTQ**; **fine-tuning experiments → bnb NF4**.
|
|
68
|
+
Getting or converting to a format is a `huggingface` (convert) / `ollama` / `vllm` job.
|
|
69
|
+
|
|
70
|
+
## Decoding a GGUF quant tag
|
|
71
|
+
|
|
72
|
+
`Q4_K_M`:
|
|
73
|
+
- **`Q4`** — nominal ~4-bit weights.
|
|
74
|
+
- **`_K`** — a **k-quant**: mixed precision that keeps the more error-sensitive tensors (attention,
|
|
75
|
+
some feed-forward) at higher bit-depth than the bulk. Better quality than the old flat `Q4_0`.
|
|
76
|
+
- **`_M`** — size/quality **tier**: `_S` (small, lower), `_M` (medium — the balanced default),
|
|
77
|
+
`_L` (large, higher). There are also non-K legacy tags (`Q4_0`, `Q4_1`, `Q5_0`…).
|
|
78
|
+
|
|
79
|
+
Quality ladder (rough): `fp16` ≥ `Q8_0` (near-lossless, ~1 byte/param) > `Q6_K` > `Q5_K_M` >
|
|
80
|
+
**`Q4_K_M`** (standard default, ~half of fp16 for a few % loss) > `Q3_K` > `Q2_K` (noticeable
|
|
81
|
+
degradation). **Do not drop below Q4 to cram a too-big model onto a too-small GPU** — the quality
|
|
82
|
+
falls off fast and you'll often still OOM at real context. Pick a smaller model instead.
|
|
83
|
+
|
|
84
|
+
## Selection heuristic
|
|
85
|
+
|
|
86
|
+
1. Estimate weights_GB at 4-bit for the sizes you're considering.
|
|
87
|
+
2. Keep it **comfortably under** your VRAM (leave ~20–30% for KV cache + overhead + context).
|
|
88
|
+
3. If nothing that fits passes your eval, the honest options are: a better-tuned smaller model, a
|
|
89
|
+
bigger box (route to `runpod`/`modal`), or `vllm` tensor-parallel — **not** sub-Q4 desperation.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: training-data
|
|
3
|
+
description: "Use when assembling or curating the corpus a fine-tune trains on: turning raw examples into JSONL in the format a trainer expects (Alpaca instruction, conversational messages, DPO preference pairs, KTO binary-label), matching your data to the model's chat template, generating synthetic or distilled examples, deduplicating and decontaminating against eval sets, or quality-filtering. Triggers: 'what format should my fine-tuning dataset be in', 'build a DPO preference dataset', 'convert my Q&A into the messages/chat format', 'my chat template does not match my training data', 'generate synthetic instruction data with distilabel', 'dedup and decontaminate my training set', 'quants exemples necessito i com filtro la qualitat del dataset abans d'entrenar'. NOT cleaning tabular rows/nulls/dtypes (that is data-cleaning), NOT building a retrieval corpus of chunks+embeddings (that is embeddings-search), NOT running the trainer or picking LoRA hyperparameters (that is finetuning/unsloth)."
|
|
4
|
+
tags: [training-data, fine-tuning-dataset, jsonl, chat-template, preference-data, dpo, kto, synthetic-data, decontamination, dataset-curation]
|
|
5
|
+
recommends: [finetuning, unsloth, huggingface, data-cleaning]
|
|
6
|
+
origin: risco
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# training-data — the corpus a fine-tune actually eats
|
|
10
|
+
|
|
11
|
+
You own the **training corpus**: the JSONL of chat turns, instruction triples, or preference
|
|
12
|
+
pairs that a trainer reads. The deliverable is a validated, deduplicated, decontaminated,
|
|
13
|
+
license-clean file in the **exact shape the trainer expects**, rendered through the **target
|
|
14
|
+
model's chat template**. You stop the moment that file loads cleanly and round-trips through
|
|
15
|
+
`apply_chat_template`. You do not choose LoRA rank or launch the run — that is
|
|
16
|
+
[`finetuning`](../finetuning/SKILL.md) / [`unsloth`](../unsloth/SKILL.md).
|
|
17
|
+
|
|
18
|
+
**Loud boundary.** This is *LLM training corpora* — messages, instruction triples, preference
|
|
19
|
+
pairs. It is **not**:
|
|
20
|
+
|
|
21
|
+
- Tabular row cleaning — nulls, dtypes, dedupe of CSV rows, category normalization → [`data-cleaning`](../data-cleaning/SKILL.md).
|
|
22
|
+
- A *retrieval* corpus — chunking documents and embedding them for search → [`embeddings-search`](../embeddings-search/SKILL.md).
|
|
23
|
+
- Actually training or serving — hyperparameters, the run, export → [`finetuning`](../finetuning/SKILL.md), [`unsloth`](../unsloth/SKILL.md), [`huggingface`](../huggingface/SKILL.md).
|
|
24
|
+
|
|
25
|
+
**Version reality (verified July 2026 — re-verify, these move monthly).** TRL is on the **v1.x**
|
|
26
|
+
line (its dataset-formats doc was tagged `v1.8.0` at author time); `transformers` is in the
|
|
27
|
+
**4.57+** era (mixed text+vision data needs ≥4.57); `datasets` is **4.x** (the `Json()` feature
|
|
28
|
+
type needs ≥4.7). Pin whatever you install — do not trust these numbers as current.
|
|
29
|
+
|
|
30
|
+
## 1. The format the trainer expects (pick by trainer, not by taste)
|
|
31
|
+
|
|
32
|
+
The trainer dictates the columns. Get this wrong and TRL either errors or, worse, trains on a
|
|
33
|
+
mangled string. Two axes: **format** (`standard` = plain strings vs `conversational` =
|
|
34
|
+
`messages` lists) and **type** (the task). One JSON object per line = JSONL.
|
|
35
|
+
|
|
36
|
+
| Trainer | Dataset type | Required keys |
|
|
37
|
+
| --- | --- | --- |
|
|
38
|
+
| `SFTTrainer` | language-modeling **or** prompt-completion | `messages` / `text`, or `prompt`+`completion` |
|
|
39
|
+
| `DPOTrainer`, `ORPOTrainer`, `CPOTrainer` | preference (explicit prompt recommended) | `prompt`, `chosen`, `rejected` |
|
|
40
|
+
| `KTOTrainer`, `BCOTrainer` | unpaired preference (binary label) | `prompt`, `completion`, `label` |
|
|
41
|
+
| `RewardTrainer` | preference (implicit prompt) | `chosen`, `rejected` |
|
|
42
|
+
| `GRPOTrainer`, `RLOOTrainer`, `PPOTrainer` | prompt-only | `prompt` |
|
|
43
|
+
|
|
44
|
+
Tiny JSONL of each (conversational values are **lists of `{role, content}`**; `label` is a JSON
|
|
45
|
+
boolean):
|
|
46
|
+
|
|
47
|
+
```jsonl
|
|
48
|
+
# Alpaca instruction (standard) — classic; NOT a native TRL type, see below
|
|
49
|
+
{"instruction": "Classify the sentiment.", "input": "The battery dies in an hour.", "output": "negative"}
|
|
50
|
+
|
|
51
|
+
# Conversational messages (SFT) — the default for chat fine-tunes
|
|
52
|
+
{"messages": [{"role": "system", "content": "You are a terse support agent."}, {"role": "user", "content": "My order never arrived."}, {"role": "assistant", "content": "Sorry about that — what is your order number?"}]}
|
|
53
|
+
|
|
54
|
+
# Preference pair (DPO) — chosen beats rejected for the same prompt
|
|
55
|
+
{"prompt": [{"role": "user", "content": "Define a hash map in one sentence."}], "chosen": [{"role": "assistant", "content": "A hash map stores key-value pairs and finds a value by hashing its key to a bucket, giving average O(1) lookup."}], "rejected": [{"role": "assistant", "content": "It's a fast dictionary thing."}]}
|
|
56
|
+
|
|
57
|
+
# KTO / unpaired preference — one completion + a good/bad boolean label
|
|
58
|
+
{"prompt": [{"role": "user", "content": "Define a hash map in one sentence."}], "completion": [{"role": "assistant", "content": "It's a fast dictionary thing."}], "label": false}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Alpaca is not a native TRL type.** `{instruction, input, output}` is the Stanford-Alpaca
|
|
62
|
+
convention, still common in Unsloth notebooks, but TRL trains on `text`/`messages`/`prompt`+
|
|
63
|
+
`completion`. You must either (a) map it into `messages` (instruction+input → user, output →
|
|
64
|
+
assistant), or (b) render it into a single `text` string via a prompt template — **and append
|
|
65
|
+
the EOS token yourself**, or the model never learns to stop (the #1 Unsloth-Alpaca bug). Prefer
|
|
66
|
+
(a) `messages` for chat models. Full field matrix, tool-calling (`tools` column) and vision
|
|
67
|
+
(`images`) extras, and every type→type conversion live in `references/formats.md`.
|
|
68
|
+
|
|
69
|
+
## 2. Chat templates — the silent run-wrecker
|
|
70
|
+
|
|
71
|
+
A chat template is a **Jinja** string stored in the tokenizer (in `tokenizer_config.json` under
|
|
72
|
+
`chat_template`, or a standalone `chat_template.jinja` in newer tokenizers). It maps a `messages`
|
|
73
|
+
list to the exact token string the model was trained on — special tokens (`<|im_start|>`,
|
|
74
|
+
`[INST]`, `<|start_header_id|>`, …) and all. You render it, you never hand-type it:
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
from transformers import AutoTokenizer
|
|
78
|
+
tok = AutoTokenizer.from_pretrained("<target-model>") # the model you will fine-tune
|
|
79
|
+
|
|
80
|
+
# TRAINING: no trailing generation prompt — the assistant turn is already in the data
|
|
81
|
+
text = tok.apply_chat_template(msgs, tokenize=False, add_generation_prompt=False)
|
|
82
|
+
|
|
83
|
+
# INFERENCE: add_generation_prompt=True appends the assistant turn-start so the model continues
|
|
84
|
+
prompt = tok.apply_chat_template(msgs, tokenize=False, add_generation_prompt=True)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Three ways this silently destroys a run — **no error, just a worse model**:
|
|
88
|
+
|
|
89
|
+
- **Hand-formatting the tokens.** Writing `<|im_start|>user\n…` strings yourself and getting one
|
|
90
|
+
token, one newline, or the BOS wrong. Train-time string ≠ inference-time string → the model
|
|
91
|
+
learns a distribution it is never served. Always render via `apply_chat_template`.
|
|
92
|
+
- **Using the wrong model's template.** The template must be the one of the model you are
|
|
93
|
+
fine-tuning. Copy Llama's template onto a Qwen fine-tune and every example is subtly malformed.
|
|
94
|
+
- **A base model with no template at all.** Base (non-instruct) checkpoints often ship
|
|
95
|
+
`chat_template = None`. `apply_chat_template` then raises — you must **choose and attach** a
|
|
96
|
+
template (e.g. ChatML) and use that same one at inference forever after.
|
|
97
|
+
|
|
98
|
+
Also decide **loss masking**: for chat SFT you usually train only on the assistant tokens
|
|
99
|
+
(`completion_only_loss` / assistant-only masking in SFTTrainer, or a completion-only collator),
|
|
100
|
+
so the model is not penalized for "predicting" the user's words. TRL applies the template for
|
|
101
|
+
you when the dataset is conversational — let it, rather than pre-flattening to `text`.
|
|
102
|
+
|
|
103
|
+
## 3. Synthetic data & distillation
|
|
104
|
+
|
|
105
|
+
Not enough real examples? Generate them. Two workhorses: **Self-Instruct** (seed a few
|
|
106
|
+
hand-written examples, prompt a strong model to produce more, filter) and **Evol-Instruct**
|
|
107
|
+
(iteratively mutate prompts to be harder/deeper). Wrap them in a pipeline framework rather than
|
|
108
|
+
ad-hoc loops (see §7).
|
|
109
|
+
|
|
110
|
+
**Licensing trap — read before you distill.** Generating your training data from *another
|
|
111
|
+
model's outputs* ("distillation") is a **terms-of-service question, not just a quality one**.
|
|
112
|
+
Some providers' terms restrict using their outputs to train competing models; some open-weight
|
|
113
|
+
licenses carry naming/derivative obligations (e.g. Llama-derived data/models may inherit naming
|
|
114
|
+
requirements). Never assert a model's license from memory — check the specific model card and
|
|
115
|
+
provider ToS at author time (licenses change). If in doubt, distill from an
|
|
116
|
+
openly-licensed-for-this-use model, and record the provenance per example.
|
|
117
|
+
|
|
118
|
+
## 4. Dedup + decontamination (skip these and your numbers lie)
|
|
119
|
+
|
|
120
|
+
- **Dedup.** Exact dedup is trivial (hash the text). Real corpora need **near-dup** removal:
|
|
121
|
+
**MinHash + LSH** (Jaccard similarity over shingles) catches templated/boilerplate repeats
|
|
122
|
+
that inflate a few patterns. Dupes waste compute and bias the model toward whatever is
|
|
123
|
+
over-represented.
|
|
124
|
+
- **Decontamination — the one people forget.** Remove any training example that overlaps your
|
|
125
|
+
**eval / benchmark test sets** (n-gram overlap, e.g. long-n-gram match against MMLU, GSM8K,
|
|
126
|
+
your own held-out set). If test items leak into training, your eval score is **inflated** and
|
|
127
|
+
meaningless — you measured memorization, not capability. Decontaminate *against every metric
|
|
128
|
+
you will report*, including your private eval. Code for both in `references/synthesis-dedup-quality.md`.
|
|
129
|
+
|
|
130
|
+
## 5. Quality filtering — a few thousand clean beats a noisy dump
|
|
131
|
+
|
|
132
|
+
**LIMA** (*Less Is More for Alignment*, arXiv **2305.11206**) is the anchor: ~1,000 carefully
|
|
133
|
+
curated examples produced a strong instruction-follower — for **alignment/style** SFT, quality
|
|
134
|
+
and diversity dominate raw volume. (This is about teaching *behavior/format*, not injecting a
|
|
135
|
+
lot of new *knowledge* — a broad knowledge shift still wants scale.) Cheap, high-leverage
|
|
136
|
+
filters, applied before you spend GPU hours:
|
|
137
|
+
|
|
138
|
+
- **Length/format**: drop empty or truncated turns, runaway-length outliers, malformed JSON,
|
|
139
|
+
wrong-role sequences (two `assistant` turns in a row, missing final assistant turn for SFT).
|
|
140
|
+
- **Dedup + decontam** from §4.
|
|
141
|
+
- **Diversity**: cluster/embed and prune near-identical intents so the set is not 80% one task.
|
|
142
|
+
- **Model/heuristic scoring**: rate helpfulness/correctness (a reward model or an LLM judge) and
|
|
143
|
+
keep the top slice — but audit the judge, LLM-as-judge has its own biases.
|
|
144
|
+
|
|
145
|
+
## 6. Licensing — two separate questions
|
|
146
|
+
|
|
147
|
+
1. **The dataset's own license** — what *you* release the JSONL under, and whether you *can*
|
|
148
|
+
release it (aggregating others' data does not launder their licenses).
|
|
149
|
+
2. **Source-usage restrictions** — the terms on where each example *came from*: scraped-site
|
|
150
|
+
ToS, the license of any base dataset you built on, and the model-output ToS from §3. These
|
|
151
|
+
bind even if you never publish. Keep a provenance column so an audit can trace every row.
|
|
152
|
+
|
|
153
|
+
State the license *class* and point at the source; never freeze a license as bare fact.
|
|
154
|
+
|
|
155
|
+
## 7. Tooling
|
|
156
|
+
|
|
157
|
+
- **distilabel** (Argilla, now under Hugging Face) — the go-to synthetic-data / AI-feedback
|
|
158
|
+
pipeline framework: composable `Step`/`Task` graphs (`TextGeneration`, `UltraFeedback`,
|
|
159
|
+
`EvolInstruct`), serializable to YAML/JSON, outputs a `Distiset` you push to the Hub. v1.x.
|
|
160
|
+
- **Argilla** — human-in-the-loop annotation/review UI to label and vet examples.
|
|
161
|
+
- **HF `datasets`** — load/`map`/`filter`/`push_to_hub`; the substrate everything else speaks.
|
|
162
|
+
- **Lilac** — dataset exploration/clustering for quality triage. **[verify — the open-source
|
|
163
|
+
repo was archived (read-only) around July 2025 after the Databricks acquisition]**; treat as
|
|
164
|
+
unmaintained OSS and confirm before depending on it.
|
|
165
|
+
|
|
166
|
+
## Worked lifecycle (build → validate → dedup → decontaminate → format → push)
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
from datasets import load_dataset
|
|
170
|
+
from transformers import AutoTokenizer
|
|
171
|
+
|
|
172
|
+
ds = load_dataset("json", data_files="raw.jsonl", split="train")
|
|
173
|
+
tok = AutoTokenizer.from_pretrained("<target-model>")
|
|
174
|
+
|
|
175
|
+
# 1. VALIDATE shape + render every row through the template (catches template errors NOW,
|
|
176
|
+
# not after 3 GPU-hours). A base model with chat_template=None raises here — attach one.
|
|
177
|
+
def render(ex):
|
|
178
|
+
return {"text": tok.apply_chat_template(ex["messages"], tokenize=False,
|
|
179
|
+
add_generation_prompt=False)}
|
|
180
|
+
ds = ds.filter(lambda ex: isinstance(ex.get("messages"), list) and ex["messages"]
|
|
181
|
+
and ex["messages"][-1]["role"] == "assistant") # SFT: must end on assistant
|
|
182
|
+
ds = ds.map(render)
|
|
183
|
+
|
|
184
|
+
# 2. DEDUP (near-dup) and 3. DECONTAMINATE against your eval set — see references for MinHash
|
|
185
|
+
# + n-gram code; both are one filter pass each.
|
|
186
|
+
|
|
187
|
+
# 4. PUSH with a data card recording license + provenance.
|
|
188
|
+
ds.push_to_hub("me/support-sft", private=True)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Deep code — MinHash/LSH dedup, n-gram decontamination, a distilabel Self-Instruct pipeline, and
|
|
192
|
+
the full conversion matrix — is in `references/`.
|
|
193
|
+
|
|
194
|
+
## Guardrails / gotchas
|
|
195
|
+
|
|
196
|
+
- **Wrong format for the trainer** = hard error or silent garbage. Match the table in §1 to your
|
|
197
|
+
trainer before generating a single row.
|
|
198
|
+
- **Hand-typed chat tokens** train a distribution you never serve. Render via `apply_chat_template`.
|
|
199
|
+
- **No EOS in Alpaca-`text` formatting** → the model never stops. Append it.
|
|
200
|
+
- **Skipped decontamination** → inflated eval; you measured leakage. Non-negotiable.
|
|
201
|
+
- **Distilling model outputs** can violate ToS. Provenance + license check first.
|
|
202
|
+
- **Quantity worship** — a noisy 500k dump loses to a curated few-thousand for alignment (LIMA).
|
|
203
|
+
- `label` in KTO/unpaired data is a JSON boolean (`true`/`false`), not the strings `"true"`/`"1"`.
|
|
204
|
+
|
|
205
|
+
## Related skills
|
|
206
|
+
|
|
207
|
+
- [`finetuning`](../finetuning/SKILL.md) — consumes this corpus: chooses SFT vs DPO vs KTO,
|
|
208
|
+
LoRA/QLoRA, hyperparameters, runs trl/peft. You hand it the file; it trains.
|
|
209
|
+
- [`unsloth`](../unsloth/SKILL.md) — one fast single-GPU training backend + GGUF export;
|
|
210
|
+
its notebooks expect exactly the Alpaca/`messages` shapes you produce here.
|
|
211
|
+
- [`huggingface`](../huggingface/SKILL.md) — the Hub you `push_to_hub` the dataset to, model
|
|
212
|
+
cards, and hosted/routed inference of the *result*.
|
|
213
|
+
- [`data-cleaning`](../data-cleaning/SKILL.md) — upstream when your raw source is dirty *tabular*
|
|
214
|
+
rows; it hands you clean rows, you turn rows into training examples.
|
|
215
|
+
|
|
216
|
+
## Checklist
|
|
217
|
+
|
|
218
|
+
- [ ] Format matches the target **trainer** (§1 table); one JSON object per line.
|
|
219
|
+
- [ ] Every row renders through the **target model's** `apply_chat_template` without error.
|
|
220
|
+
- [ ] SFT rows end on an `assistant` turn; preference rows have distinct `chosen`/`rejected`; KTO `label` is a boolean.
|
|
221
|
+
- [ ] Loss masking / EOS handling decided (assistant-only loss; EOS appended if flattening to `text`).
|
|
222
|
+
- [ ] Near-duplicates removed (MinHash/LSH); exact dupes gone.
|
|
223
|
+
- [ ] **Decontaminated** against every eval/benchmark you will report.
|
|
224
|
+
- [ ] Quality-filtered (length/format/diversity/score) — curated over bulk.
|
|
225
|
+
- [ ] Dataset license set **and** source-usage/model-output ToS checked; provenance recorded.
|
|
226
|
+
- [ ] Data card written; pushed (private first).
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Evals for the `training-data` skill
|
|
2
|
+
|
|
3
|
+
Routing + capability checks read from `cases.yaml` by the skill eval harness — no network, no
|
|
4
|
+
model calls, nothing to install. The `should_trigger` prompts must select this skill: they cover
|
|
5
|
+
format-by-trainer (DPO), converting raw pairs to `messages`, the non-obvious "model never stops /
|
|
6
|
+
I hand-formatted the chat tokens" template-mismatch case, synthetic-data + dedup, decontamination
|
|
7
|
+
against benchmarks, and a Catalan quality-filtering prompt. The `should_not_trigger` prompts must
|
|
8
|
+
route to the named real sibling instead — `data-cleaning` (tabular rows), `embeddings-search`
|
|
9
|
+
(retrieval corpus), `finetuning` / `unsloth` (running the trainer + export), `prompt-engineering`
|
|
10
|
+
(inference prompt craft). The single `capability` case is a rubric: a good answer to the
|
|
11
|
+
support-transcript scenario must hit every `must_include` bullet — the messages/JSONL shape, chat-
|
|
12
|
+
template rendering via `apply_chat_template`, dedup + decontamination, LIMA quality-over-quantity,
|
|
13
|
+
and the license/provenance + distillation-ToS guardrail.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
skill: training-data
|
|
2
|
+
|
|
3
|
+
should_trigger:
|
|
4
|
+
- prompt: "What format should my fine-tuning dataset be in if I want to run DPO?"
|
|
5
|
+
why: "Core format-by-trainer decision — preference type {prompt, chosen, rejected}. Squarely this skill."
|
|
6
|
+
- prompt: "I have thousands of Q&A pairs. Convert them into the conversational messages format for SFT."
|
|
7
|
+
why: "Turning raw examples into the messages/role-content JSONL a trainer eats — the central deliverable."
|
|
8
|
+
- prompt: "My fine-tuned chat model never stops generating and repeats itself. I formatted the training data myself with the chat tokens."
|
|
9
|
+
why: "Non-obvious: hand-typed chat tokens / missing EOS = train/inference template mismatch. User never names the fix; this skill diagnoses it."
|
|
10
|
+
- prompt: "Generate synthetic instruction-tuning data with distilabel and then deduplicate it before training."
|
|
11
|
+
why: "Synthetic data (§3) + dedup (§4) — distilabel pipeline and MinHash, both this skill."
|
|
12
|
+
- prompt: "Do I need to decontaminate my training set against MMLU before I trust my eval numbers?"
|
|
13
|
+
why: "Decontamination against benchmark test sets — the load-bearing guardrail; leakage inflates eval."
|
|
14
|
+
- prompt: "Quants exemples necessito i com filtro la qualitat del dataset abans d'entrenar un model?"
|
|
15
|
+
why: "Catalan; quality-over-quantity filtering (LIMA) before training. This skill's §5."
|
|
16
|
+
|
|
17
|
+
should_not_trigger:
|
|
18
|
+
- prompt: "Clean this messy CSV: fix the nulls and sentinels, dedupe the rows, and normalize the category column."
|
|
19
|
+
route_to: data-cleaning
|
|
20
|
+
why: "Tabular row cleaning (nulls/dtypes/dupe rows) — the explicit boundary; not an LLM training corpus."
|
|
21
|
+
- prompt: "Chunk our documentation, embed it, and build an index so we can retrieve relevant passages."
|
|
22
|
+
route_to: embeddings-search
|
|
23
|
+
why: "A retrieval corpus of chunks+embeddings, not a training corpus of messages/preference pairs."
|
|
24
|
+
- prompt: "Set the LoRA rank, learning rate, and batch size and launch the QLoRA fine-tune."
|
|
25
|
+
route_to: finetuning
|
|
26
|
+
why: "Running the trainer and choosing hyperparameters — training-data stops at the validated file."
|
|
27
|
+
- prompt: "Run the fine-tune on my single 4090 with Unsloth and export the result to GGUF for Ollama."
|
|
28
|
+
route_to: unsloth
|
|
29
|
+
why: "The actual training backend + export, not corpus preparation."
|
|
30
|
+
- prompt: "Help me write a better system prompt so the model returns clean JSON at inference time."
|
|
31
|
+
route_to: prompt-engineering
|
|
32
|
+
why: "Prompt craft for inference, no training corpus involved."
|
|
33
|
+
|
|
34
|
+
capability:
|
|
35
|
+
- scenario: "I have 8,000 raw customer-support transcripts and want to fine-tune a chat model on them. Prepare the dataset."
|
|
36
|
+
must_include:
|
|
37
|
+
- "convert to conversational `messages` (role/content) — or Alpaca instruction/input/output — as JSONL, one JSON object per line, ending each SFT example on an assistant turn"
|
|
38
|
+
- "render through the TARGET model's chat template via apply_chat_template (add_generation_prompt=False for training) instead of hand-writing special tokens, because a template mismatch silently wrecks the run with no error"
|
|
39
|
+
- "deduplicate near-duplicates (MinHash/LSH) and decontaminate against the eval/benchmark test sets, or the reported eval score is inflated"
|
|
40
|
+
- "quality-filter over raw volume (LIMA, arXiv 2305.11206) — a few thousand curated examples beat a large noisy dump for alignment"
|
|
41
|
+
- "record the dataset license AND check source-usage/model-output terms — distilling another model's outputs may violate its ToS; keep per-example provenance"
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Dataset formats — full field matrix & conversions
|
|
2
|
+
|
|
3
|
+
Grounded in the TRL "Dataset formats and types" doc (tagged `v1.8.0` at author time). TRL and
|
|
4
|
+
`datasets` move monthly — verify field names against the current TRL docs before you rely on
|
|
5
|
+
them. Field names below are verbatim from that doc.
|
|
6
|
+
|
|
7
|
+
## The two axes
|
|
8
|
+
|
|
9
|
+
- **Format** — `standard` (plain-text string values) vs `conversational` (values are lists of
|
|
10
|
+
`{"role", "content"}` messages). Conversational is the default for chat models.
|
|
11
|
+
- **Type** — the task, which sets the columns.
|
|
12
|
+
|
|
13
|
+
| Type | Standard | Conversational |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| Language modeling | `{"text": "..."}` | `{"messages": [{"role","content"}, ...]}` |
|
|
16
|
+
| Prompt-only | `{"prompt": "..."}` | `{"prompt": [ ... ]}` |
|
|
17
|
+
| Prompt-completion | `{"prompt", "completion"}` | `{"prompt": [...], "completion": [...]}` |
|
|
18
|
+
| Preference (explicit) | `{"prompt", "chosen", "rejected"}` | same keys, each a message list |
|
|
19
|
+
| Preference (implicit) | `{"chosen", "rejected"}` (no `prompt`) | same, each a full conversation |
|
|
20
|
+
| Unpaired preference (KTO) | `{"prompt", "completion", "label"}` | same, `label` a bool |
|
|
21
|
+
| Stepwise supervision | `{"prompt", "completions": [...], "labels": [bool,...]}` | — |
|
|
22
|
+
|
|
23
|
+
`label` / `labels` are JSON booleans (`true`/`false`).
|
|
24
|
+
|
|
25
|
+
## Which trainer wants which type
|
|
26
|
+
|
|
27
|
+
| Trainer | Type |
|
|
28
|
+
| --- | --- |
|
|
29
|
+
| `SFTTrainer` | language modeling **or** prompt-completion |
|
|
30
|
+
| `DPOTrainer` | preference (explicit prompt recommended) |
|
|
31
|
+
| `KTOTrainer` | unpaired preference, or preference |
|
|
32
|
+
| `RewardTrainer` | preference (implicit prompt recommended) |
|
|
33
|
+
| `GRPOTrainer`, `RLOOTrainer`, `OnlineDPO/Nash/XPO` | prompt-only |
|
|
34
|
+
| `ORPOTrainer`, `CPOTrainer`, `BCOTrainer` | preference (explicit) / unpaired |
|
|
35
|
+
| `PRMTrainer` | stepwise supervision |
|
|
36
|
+
| `PPOTrainer` | tokenized language modeling |
|
|
37
|
+
|
|
38
|
+
Experimental trainers live under `trl.experimental.*` — confirm the import path in the current
|
|
39
|
+
release.
|
|
40
|
+
|
|
41
|
+
## Alpaca instruction format (classic, not native TRL)
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{"instruction": "Summarize the paragraph.", "input": "<long text>", "output": "<summary>"}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`input` is optional (empty string when the instruction is self-contained). TRL does not train on
|
|
48
|
+
these keys directly. Convert:
|
|
49
|
+
|
|
50
|
+
**To `messages` (preferred for chat models):**
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
def alpaca_to_messages(ex):
|
|
54
|
+
user = ex["instruction"] + (("\n\n" + ex["input"]) if ex.get("input") else "")
|
|
55
|
+
return {"messages": [{"role": "user", "content": user},
|
|
56
|
+
{"role": "assistant", "content": ex["output"]}]}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**To a single `text` string via a prompt template (Unsloth-style) — append EOS:**
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
TEMPLATE = ("### Instruction:\n{instruction}\n\n### Input:\n{input}\n\n### Response:\n{output}")
|
|
63
|
+
def alpaca_to_text(ex, eos):
|
|
64
|
+
return {"text": TEMPLATE.format(**ex) + eos} # eos = tokenizer.eos_token — REQUIRED
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Without the EOS token the model never learns to stop generating. When formatting to `text` you
|
|
68
|
+
are also bypassing the chat template, so this path is for base/completion-style training; for
|
|
69
|
+
chat models prefer `messages` + `apply_chat_template`.
|
|
70
|
+
|
|
71
|
+
## Tool-calling data
|
|
72
|
+
|
|
73
|
+
Add a `tools` column (list of JSON-schema function specs); assistant turns carry `tool_calls`
|
|
74
|
+
instead of `content`, and tool results come back as a `{"role": "tool", ...}` message.
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
from transformers.utils import get_json_schema # build the schema from a Python signature
|
|
78
|
+
schema = get_json_schema(my_function)
|
|
79
|
+
row = {"messages": [...], "tools": [schema]}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
On `datasets` ≥4.7 use the `Json()` feature type for arbitrary tool-arg objects
|
|
83
|
+
(`Dataset.from_list(data, on_mixed_types="use_json")`); on older `datasets` store `tools` as a
|
|
84
|
+
`json.dumps(...)` string.
|
|
85
|
+
|
|
86
|
+
## Vision (VLM) data
|
|
87
|
+
|
|
88
|
+
Add an `images` key (list of PIL images per row) or `image` (single), and make each message
|
|
89
|
+
`content` a list of typed parts:
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
"content": [{"type": "image"}, {"type": "text", "text": "What is in the image?"}]
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Mixing text-only and image rows in one dataset needs `transformers` ≥ 4.57.
|
|
96
|
+
|
|
97
|
+
## Type→type conversions (with `datasets`)
|
|
98
|
+
|
|
99
|
+
- **prompt-completion → language-modeling**: concatenate `prompt` + `completion` into `text`.
|
|
100
|
+
- **preference → prompt-completion**: drop `rejected`, rename `chosen` → `completion`.
|
|
101
|
+
- **preference → prompt-only**: drop `chosen` and `rejected`.
|
|
102
|
+
- **implicit → explicit preference**: `trl.extract_prompt` pulls the shared prefix into `prompt`.
|
|
103
|
+
- **preference → unpaired (KTO)**: `trl.unpair_preference_dataset` — **only valid if every
|
|
104
|
+
`chosen` is genuinely good and every `rejected` genuinely bad** (KTO's label is absolute
|
|
105
|
+
good/bad, not relative). If your pairs are "better vs worse" but both acceptable, unpairing
|
|
106
|
+
mislabels them.
|
|
107
|
+
- **stepwise → unpaired**: join `completions`, merge `labels` (e.g. logical AND).
|
|
108
|
+
|
|
109
|
+
Do conversions **before** `apply_chat_template`, on the structured `messages`, so they behave
|
|
110
|
+
consistently across formats.
|
|
111
|
+
|
|
112
|
+
## Sanity checks worth automating
|
|
113
|
+
|
|
114
|
+
- Every SFT conversational row ends on an `assistant` turn.
|
|
115
|
+
- Roles alternate sensibly; no empty `content`.
|
|
116
|
+
- Preference `chosen != rejected`.
|
|
117
|
+
- KTO `label` present and boolean; class balance is not 100/0.
|
|
118
|
+
- The whole file round-trips through `apply_chat_template` for the *target* model with no raise.
|