Codeseys's picture
Wave 14: close every Wave 13 review finding + 4 documentation files; Wave 14b: real PRIME-RL parity + multi-process DiLoCo convergence
d9dd3a5
Raw
History Blame Contribute Delete
4.35 kB
# Default replaysim normalization recipe.
#
# This is a data-juicer YAML config (https://github.com/modelscope/data-juicer).
# It runs CPU-only ops that filter and clean DPO pairs produced by
# composer_replication.teacher_replay.extract_dpo_pairs.
#
# The op-graph operates on records of shape:
#
# {
# "state_id": "...",
# "messages": [{"role": "user", "content": "..."}], # context
# # --- flat-string shape (consumed by length/word/special-char/dedup filters) ---
# "chosen": "the chosen response as a plain string",
# "rejected": "the rejected response as a plain string",
# # --- chat-messages shape (preserved for chat-aware ops + round-trip) ---
# "chosen_messages": [{"role": "assistant", "content": "..."}],
# "rejected_messages": [{"role": "assistant", "content": "..."}],
# "n_teachers_agreeing": 2
# }
#
# IMPORTANT — field-key contract:
# data-juicer's `text_length_filter`, `words_num_filter`,
# `special_characters_filter` and `document_deduplicator` all read a SINGLE
# string field named by `text_key` (singular). They expect plain strings.
# Pointing them at a list-of-dicts (the chat-messages shape) crashes or
# silently no-ops. We therefore keep two parallel representations:
# * `chosen` / `rejected` — plain strings, fed to filter ops below.
# * `chosen_messages` / `rejected_messages` — chat-messages list, preserved
# untouched for downstream chat-aware consumers and the round-trip.
#
# data-juicer caveat: each filter op accepts only ONE `text_key`. To filter
# both `chosen` AND `rejected`, we duplicate each op — once with
# `text_key: chosen`, once with `text_key: rejected`. The top-level
# `text_keys: chosen` below also satisfies data-juicer's dataset-load
# validation (the formatter checks the global text_key exists in the dataset).
#
# Ops listed in `process` are applied in order. Each op operates on the
# full record but reads/writes one field.
# Project & I/O are filled in by DJNormalizer at runtime; we only
# specify the op pipeline here.
# --- Global text-key contract (see header note) -----------------------
# data-juicer validates this exists on the dataset before any op runs, and
# uses it as the default text_key for ops that don't specify their own.
text_keys: chosen
# --- Op pipeline (applied in order) -----------------------------------
process:
# 1. Length filter on the assistant response.
# Drops pairs where either the chosen or rejected response is shorter
# than 8 chars or longer than 32k chars (likely garbled / overflow).
- text_length_filter:
min_len: 8
max_len: 32000
text_key: chosen
- text_length_filter:
min_len: 8
max_len: 32000
text_key: rejected
# 2. Word-count filter on response.
# Drops pairs with absurdly low (< 2 words) or high (> 4096 words)
# response counts.
- words_num_filter:
min_num: 2
max_num: 4096
text_key: chosen
- words_num_filter:
min_num: 2
max_num: 4096
text_key: rejected
# 3. Special-character filter.
# Drops responses where >50% of characters are non-alphabetic
# special chars (likely encoding errors or junk).
- special_characters_filter:
max_ratio: 0.5
text_key: chosen
- special_characters_filter:
max_ratio: 0.5
text_key: rejected
# 4. Per-conversation deduplication.
# Within the batch, drop records where the `chosen` field is a
# duplicate of another record's `chosen`. (data-juicer's
# document_deduplicator is per-batch hashing — full-corpus dedup is
# a separate op family.)
- document_deduplicator:
lowercase: true
ignore_non_character: true
text_key: chosen
# Notes:
# - We DO NOT run `pair_preference_mapper` because its default config may
# re-synthesize the rejected text via an LLM call — we already have
# real disagreement-derived rejected text and don't want to pay another
# API call. (See ADR-004 § "One-day spike before merge.")
# - Language detection is intentionally not in the default — it requires
# downloading a fasttext model and adds startup latency. Add the
# `language_id_score_filter` op to a custom recipe if needed.
# - Semantic-similarity dedup is GPU-bound (NeMo-Curator ops); not in
# the default.