@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.
Files changed (59) hide show
  1. package/README.md +8 -2
  2. package/manifest.json +181 -3
  3. package/package.json +1 -1
  4. package/scripts/lib/domains.js +1 -0
  5. package/scripts/lib/recommend.js +6 -0
  6. package/skills/automation-strategy/SKILL.md +2 -2
  7. package/skills/automation-strategy/references/platform-selection-matrix.md +2 -2
  8. package/skills/deep-learning/SKILL.md +263 -0
  9. package/skills/deep-learning/evals/README.md +11 -0
  10. package/skills/deep-learning/evals/cases.yaml +48 -0
  11. package/skills/deep-learning/references/distributed.md +105 -0
  12. package/skills/deep-learning/references/training-recipes.md +135 -0
  13. package/skills/finetuning/SKILL.md +244 -0
  14. package/skills/finetuning/evals/README.md +13 -0
  15. package/skills/finetuning/evals/cases.yaml +50 -0
  16. package/skills/finetuning/references/hyperparameters-and-eval.md +74 -0
  17. package/skills/finetuning/references/methods.md +189 -0
  18. package/skills/harness/references/providers.yaml +38 -2
  19. package/skills/huggingface/SKILL.md +1 -1
  20. package/skills/machine-learning/SKILL.md +260 -0
  21. package/skills/machine-learning/evals/README.md +15 -0
  22. package/skills/machine-learning/evals/cases.yaml +54 -0
  23. package/skills/machine-learning/references/gbdt-and-tuning.md +83 -0
  24. package/skills/machine-learning/references/metrics-and-imbalance.md +82 -0
  25. package/skills/machine-learning/references/pipelines-and-cv.md +135 -0
  26. package/skills/n8n/SKILL.md +1 -1
  27. package/skills/nlp/SKILL.md +225 -0
  28. package/skills/nlp/evals/README.md +10 -0
  29. package/skills/nlp/evals/cases.yaml +45 -0
  30. package/skills/nlp/references/evaluation.md +107 -0
  31. package/skills/nlp/references/tokenization.md +95 -0
  32. package/skills/open-weights/SKILL.md +239 -0
  33. package/skills/open-weights/evals/README.md +14 -0
  34. package/skills/open-weights/evals/cases.yaml +42 -0
  35. package/skills/open-weights/references/licenses.md +123 -0
  36. package/skills/open-weights/references/model-families.md +83 -0
  37. package/skills/open-weights/references/sizing-and-quant.md +89 -0
  38. package/skills/roast-me/tools/adapters/__pycache__/__init__.cpython-312.pyc +0 -0
  39. package/skills/roast-me/tools/adapters/__pycache__/base.cpython-312.pyc +0 -0
  40. package/skills/roast-me/tools/adapters/__pycache__/claude.cpython-312.pyc +0 -0
  41. package/skills/roast-me/tools/adapters/__pycache__/codex.cpython-312.pyc +0 -0
  42. package/skills/roast-me/tools/adapters/__pycache__/gemini.cpython-312.pyc +0 -0
  43. package/skills/roast-me/tools/adapters/__pycache__/registry.cpython-312.pyc +0 -0
  44. package/skills/training-data/SKILL.md +226 -0
  45. package/skills/training-data/evals/README.md +13 -0
  46. package/skills/training-data/evals/cases.yaml +41 -0
  47. package/skills/training-data/references/formats.md +118 -0
  48. package/skills/training-data/references/synthesis-dedup-quality.md +134 -0
  49. package/skills/unsloth/SKILL.md +254 -0
  50. package/skills/unsloth/evals/README.md +10 -0
  51. package/skills/unsloth/evals/cases.yaml +42 -0
  52. package/skills/unsloth/references/export.md +75 -0
  53. package/skills/unsloth/references/grpo.md +91 -0
  54. package/skills/unsloth/references/masking-and-templates.md +91 -0
  55. package/skills/vllm/SKILL.md +235 -0
  56. package/skills/vllm/evals/README.md +9 -0
  57. package/skills/vllm/evals/cases.yaml +47 -0
  58. package/skills/vllm/references/flags-and-endpoints.md +105 -0
  59. 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.
@@ -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.