dockyard_rl.algorithms.loss.loss_functions¶
Loss functions for Project Dockyard RL training.
Contains: ClippedPGLossFn — GRPO / PPO / REINFORCE / DAPO / GSPO clipped PG loss NLLLossFn — Negative log-likelihood (SFT auxiliary loss) PreferenceLossFn — Preference-based loss base class DPOLossFn — Direct Preference Optimisation DistillationLossFn — Forward / reverse / mixed KL distillation DraftCrossEntropyLossFn — Speculative-decoding draft model training loss
DistributedCrossEntropy is an optional dependency imported lazily.
Module Contents¶
Classes¶
Auxiliary soft-target cross-entropy for draft-model training. |
|
Generalised Clipped Policy Gradient loss. |
|
Negative Log-Likelihood loss (SFT auxiliary). |
|
Base class for preference-based losses (DPO, IPO, etc.). |
|
Direct Preference Optimisation loss. |
|
Conservative DPO (cDPO) — label-smoothed preference loss. |
|
DPO-positive (DPOP) — adds a positive penalty that resists the chosen log-probability dropping below the reference. |
|
Length-regularised DPO (R-DPO) — subtracts an explicit length penalty from the implicit reward to disentangle preference quality from response length. |
|
Identity Preference Optimisation (IPO) — replaces the logsigmoid with a squared loss around a target margin, regularising toward the reference rather than over-fitting deterministic preferences. |
|
Kahneman-Tversky Optimisation (KTO) — unpaired preference loss. |
|
SimPO — reference-free, length-normalised preference loss with a target margin. |
|
ORPO — reference-free monolithic objective: SFT NLL plus a log-odds-ratio term. |
|
Forward / reverse / mixed KL distillation loss. |
|
Config for (multi-teacher) cross-tokenizer distillation loss. |
|
Student-side keys are fixed; teacher-side keys are teacher-indexed. |
|
Multi-teacher cross-tokenizer distillation loss. |
Functions¶
Construct the preference loss for |
|
Whether a variant needs no frozen-reference logprobs (SimPO/ORPO, D4). |
Data¶
API¶
- class dockyard_rl.algorithms.loss.loss_functions.DraftCrossEntropyLossConfig¶
Bases:
typing.TypedDict- vocab_parallel_group: Optional[torch.distributed.ProcessGroup]¶
None
- class dockyard_rl.algorithms.loss.loss_functions.DraftCrossEntropyLossDataDict¶
Bases:
typing.TypedDict- teacher_logits: torch.Tensor¶
None
- student_logits: torch.Tensor¶
None
- token_mask: torch.Tensor¶
None
- sample_mask: torch.Tensor¶
None
- student_vocab_indices: NotRequired[torch.Tensor]¶
None
- class dockyard_rl.algorithms.loss.loss_functions.DraftCrossEntropyLossFn(vocab_parallel_group: Optional[torch.distributed.ProcessGroup] = None)¶
Bases:
dockyard_rl.algorithms.loss.interfaces.LossFunctionAuxiliary soft-target cross-entropy for draft-model training.
Initialization
- loss_type¶
None
- input_type¶
None
- class dockyard_rl.algorithms.loss.loss_functions.ClippedPGLossConfig¶
Bases:
pydantic.BaseModel- disable_ppo_ratio: bool¶
False
- token_level_loss: bool¶
True
- sequence_level_importance_ratios: bool¶
False
- ratio_clip_min: float¶
0.2
- ratio_clip_max: float¶
0.2
- ratio_clip_c: Optional[float]¶
None
- reference_policy_kl_penalty: float¶
0.01
- reference_policy_kl_type: str¶
‘k3’
- kl_input_clamp_value: Optional[float]¶
20.0
- kl_output_clamp_value: Optional[float]¶
10.0
- use_kl_in_reward: bool¶
False
- use_importance_sampling_correction: bool¶
False
- truncated_importance_sampling_type: Optional[str]¶
None
- truncated_importance_sampling_ratio: Optional[float]¶
None
- truncated_importance_sampling_ratio_min: Optional[float]¶
None
- use_on_policy_kl_approximation: bool¶
False
- force_on_policy_ratio: bool¶
False
- use_cispo: bool¶
False
- class dockyard_rl.algorithms.loss.loss_functions.ClippedPGLossDataDict¶
Bases:
typing.TypedDict- input_ids: torch.Tensor¶
None
- advantages: torch.Tensor¶
None
- prev_logprobs: torch.Tensor¶
None
- generation_logprobs: torch.Tensor¶
None
- reference_policy_logprobs: torch.Tensor¶
None
- token_mask: torch.Tensor¶
None
- sample_mask: torch.Tensor¶
None
- class dockyard_rl.algorithms.loss.loss_functions.ClippedPGLossFn(cfg: dockyard_rl.algorithms.loss.loss_functions.ClippedPGLossConfig)¶
Bases:
dockyard_rl.algorithms.loss.interfaces.LossFunctionGeneralised Clipped Policy Gradient loss.
Implements PPO, GRPO, REINFORCE/RLOO, DAPO, GSPO, and dual-clipping from a single configurable loss function.
Loss formula: L(θ) = E_t[ min(r_t(θ) * A_t, clip(r_t(θ), 1-ε, 1+ε) * A_t) ] - β * KL(π_θ || π_ref)
where r_t(θ) = π_θ(a_t|s_t) / π_θ_old(a_t|s_t).
Initialization
- input_type¶
None
- class dockyard_rl.algorithms.loss.loss_functions.NLLLossFn(use_linear_ce_fusion: bool = False)¶
Bases:
dockyard_rl.algorithms.loss.interfaces.LossFunctionNegative Log-Likelihood loss (SFT auxiliary).
Initialization
- loss_type¶
None
- input_type¶
None
- class dockyard_rl.algorithms.loss.loss_functions.PreferenceLossDataDict¶
Bases:
typing.TypedDict- input_ids: torch.Tensor¶
None
- token_mask: torch.Tensor¶
None
- sample_mask: torch.Tensor¶
None
- class dockyard_rl.algorithms.loss.loss_functions.PreferenceLossFn¶
Bases:
dockyard_rl.algorithms.loss.interfaces.LossFunctionBase class for preference-based losses (DPO, IPO, etc.).
- loss_type¶
None
- input_type¶
None
- split_output_tensor(tensor: torch.Tensor) tuple[torch.Tensor, torch.Tensor]¶
- class dockyard_rl.algorithms.loss.loss_functions.DPOLossConfig¶
Bases:
typing.TypedDict- reference_policy_kl_penalty: float¶
None
- preference_loss_weight: float¶
None
- sft_loss_weight: float¶
None
- preference_average_log_probs: bool¶
None
- sft_average_log_probs: bool¶
None
- loss_variant: NotRequired[str]¶
None
- label_smoothing: NotRequired[float]¶
None
- dpop_lambda: NotRequired[float]¶
None
- length_penalty: NotRequired[float]¶
None
- desirable_weight: NotRequired[float]¶
None
- undesirable_weight: NotRequired[float]¶
None
- simpo_gamma: NotRequired[float]¶
None
- orpo_lambda: NotRequired[float]¶
None
- class dockyard_rl.algorithms.loss.loss_functions.DPOLossDataDict¶
Bases:
typing.TypedDict- input_ids: torch.Tensor¶
None
- reference_policy_logprobs: torch.Tensor¶
None
- token_mask: torch.Tensor¶
None
- sample_mask: torch.Tensor¶
None
- class dockyard_rl.algorithms.loss.loss_functions.DPOLossFn(cfg: dockyard_rl.algorithms.loss.loss_functions.DPOLossConfig, use_linear_ce_fusion: bool = False)¶
Bases:
dockyard_rl.algorithms.loss.loss_functions.PreferenceLossFnDirect Preference Optimisation loss.
Initialization
- loss_type¶
None
- input_type¶
None
- reference_free¶
False
- sequences_per_datum¶
2
- class dockyard_rl.algorithms.loss.loss_functions.CDPOLossFn(cfg: dockyard_rl.algorithms.loss.loss_functions.DPOLossConfig, use_linear_ce_fusion: bool = False)¶
Bases:
dockyard_rl.algorithms.loss.loss_functions.DPOLossFnConservative DPO (cDPO) — label-smoothed preference loss.
Mixes the flipped target with weight ε to tolerate noisy / mislabelled preferences: L = −[(1−ε)·logσ(βΔ) + ε·logσ(−βΔ)]. Reduces to DPO at ε=0.
Initialization
- class dockyard_rl.algorithms.loss.loss_functions.DPOPLossFn(cfg: dockyard_rl.algorithms.loss.loss_functions.DPOLossConfig, use_linear_ce_fusion: bool = False)¶
Bases:
dockyard_rl.algorithms.loss.loss_functions.DPOLossFnDPO-positive (DPOP) — adds a positive penalty that resists the chosen log-probability dropping below the reference.
L = −logσ(β·(Δ − λ·max(0, s_ref_chosen − s_policy_chosen)))
Mitigates the failure where both chosen and rejected log-probs fall (a capability regression). Reduces to DPO at λ=0.
Initialization
- class dockyard_rl.algorithms.loss.loss_functions.RDPOLossFn(cfg: dockyard_rl.algorithms.loss.loss_functions.DPOLossConfig, use_linear_ce_fusion: bool = False)¶
Bases:
dockyard_rl.algorithms.loss.loss_functions.DPOLossFnLength-regularised DPO (R-DPO) — subtracts an explicit length penalty from the implicit reward to disentangle preference quality from response length.
L = −logσ(β·Δ − α·(|y_chosen| − |y_rejected|))
The α penalty is outside the β scaling (per Park et al. 2024). Reduces to DPO at α=0.
Initialization
- class dockyard_rl.algorithms.loss.loss_functions.IPOLossFn(cfg: dockyard_rl.algorithms.loss.loss_functions.DPOLossConfig, use_linear_ce_fusion: bool = False)¶
Bases:
dockyard_rl.algorithms.loss.loss_functions.DPOLossFnIdentity Preference Optimisation (IPO) — replaces the logsigmoid with a squared loss around a target margin, regularising toward the reference rather than over-fitting deterministic preferences.
L = (Δ − 1/(2τ))², τ = reference_policy_kl_penalty
Distinct loss family — does not reduce to DPO at any hyperparameter.
Initialization
- class dockyard_rl.algorithms.loss.loss_functions.KTOLossFn(cfg: dockyard_rl.algorithms.loss.loss_functions.DPOLossConfig, use_linear_ce_fusion: bool = False)¶
Bases:
dockyard_rl.algorithms.loss.loss_functions.DPOLossFnKahneman-Tversky Optimisation (KTO) — unpaired preference loss.
Operates on a batch of independently-labelled examples (desirable or undesirable) rather than chosen/rejected pairs. Per example, with implicit reward (logratio) r = Σ_t (logπ − logπ_ref)·mask and a detached KL reference point z:
desirable: λ_D · (1 − σ(β·(r − z))) undesirable: λ_U · (1 − σ(β·(z − r)))
z is the policy↔reference KL estimated from mismatched completions through the current policy; it is supplied at train time via
data["kto_reference_kl"](worker-computed, detached, clamped ≥ 0). When absent it defaults to 0 (no KL anchor) — the pre-worker behaviour. Consumespreference_label(1 desirable / 0 undesirable) from the unpairedkto_collate_fn.Initialization
- sequences_per_datum¶
1
- class dockyard_rl.algorithms.loss.loss_functions.SimPOLossFn(cfg: dockyard_rl.algorithms.loss.loss_functions.DPOLossConfig, use_linear_ce_fusion: bool = False)¶
Bases:
dockyard_rl.algorithms.loss.loss_functions.DPOLossFnSimPO — reference-free, length-normalised preference loss with a target margin.
Reward is the average log-probability of the response (no reference model): s = (1/|y|) Σ_t logπ(y_t). The loss is
L = −logσ(β·(s_chosen − s_rejected) − γ)
where γ =
simpo_gammais the target reward margin. Reference-free: needs no frozen-reference logprobs.Initialization
- reference_free¶
True
- class dockyard_rl.algorithms.loss.loss_functions.ORPOLossFn(cfg: dockyard_rl.algorithms.loss.loss_functions.DPOLossConfig, use_linear_ce_fusion: bool = False)¶
Bases:
dockyard_rl.algorithms.loss.loss_functions.DPOLossFnORPO — reference-free monolithic objective: SFT NLL plus a log-odds-ratio term.
With length-normalised average log-probabilities s = (1/|y|) Σ logπ:
log_odds = (s_chosen − s_rejected) − (log1mexp(s_chosen) − log1mexp(s_rejected)) L = −s_chosen + λ·(−logσ(log_odds))
where λ =
orpo_lambdaweights the odds-ratio term against the SFT loss. Reference-free; the SFT term is the length-normalised NLL on the chosen response (sequence-weighted, matching the repo’s DPO SFT-aux convention).Initialization
- reference_free¶
True
- dockyard_rl.algorithms.loss.loss_functions.PREFERENCE_LOSS_REGISTRY: dict[str, type[dockyard_rl.algorithms.loss.loss_functions.DPOLossFn]]¶
None
- dockyard_rl.algorithms.loss.loss_functions.build_preference_loss(variant: Optional[str], cfg: dockyard_rl.algorithms.loss.loss_functions.DPOLossConfig, use_linear_ce_fusion: bool = False) dockyard_rl.algorithms.loss.loss_functions.DPOLossFn¶
Construct the preference loss for
dpo.loss_variant.A missing/None variant defaults to vanilla DPO. An unrecognised variant raises a clear error rather than silently falling back.
- dockyard_rl.algorithms.loss.loss_functions.is_reference_free(variant: Optional[str]) bool¶
Whether a variant needs no frozen-reference logprobs (SimPO/ORPO, D4).
Consulted by the DPO driver to skip the reference-logprob stage. Returns False for every variant currently registered, so the frozen-ref path is unchanged for dpo/dpop/cdpo/rdpo/ipo/kto.
- class dockyard_rl.algorithms.loss.loss_functions.DistillationLossConfig¶
Bases:
typing.TypedDict- kl_type: str¶
None
- mixed_kl_weight: float¶
None
- zero_outside_topk: bool¶
None
- class dockyard_rl.algorithms.loss.loss_functions.DistillationLossDataDict¶
Bases:
typing.TypedDict- input_ids: torch.Tensor¶
None
- input_lengths: torch.Tensor¶
None
- token_mask: torch.Tensor¶
None
- sample_mask: torch.Tensor¶
None
- teacher_topk_logits: torch.Tensor¶
None
- teacher_topk_indices: torch.Tensor¶
None
- class dockyard_rl.algorithms.loss.loss_functions.DistillationLossFn(cfg: dockyard_rl.algorithms.loss.loss_functions.DistillationLossConfig)¶
Bases:
dockyard_rl.algorithms.loss.interfaces.LossFunctionForward / reverse / mixed KL distillation loss.
Initialization
- loss_type¶
None
- input_type¶
None
- class dockyard_rl.algorithms.loss.loss_functions.CrossTokenizerDistillationLossConfig¶
Bases:
typing.TypedDictConfig for (multi-teacher) cross-tokenizer distillation loss.
gold_loss/xtoken_lossand the scalar knobs below are the global defaults shared across every teacher; the per-teacher runtime-injected lists (projection_matrix_pathsetc.) carry one entry perteachers[i]and can override the gold/xtoken flags per teacher inkd_loss_mode="sum". The single-teacher path is just a length-1 list.Attributes: gold_loss: If True, use the gold-loss formulation: split the vocab into an exact-token-mapped common set (KL) and an uncommon set (L1). xtoken_loss: Modifier inside the gold-loss path. If True, relaxes the exact-map threshold to
>= 0.6(vs== 1.0) and adds a collision-replacement rule. Requiresgold_loss=True. temperature: Softmax temperature applied symmetrically before KL. vocab_topk: Microbatch-global top-k size for the P-KL path (gold_loss=False). Inert whengold_loss=True. uncommon_topk: Cap on the L1 uncommon-tail sort in the gold path. Inert whengold_loss=False. reverse_kl: If True, KL(student || teacher) instead of KL(teacher || student). exact_token_match_only: P-KL path only — if True, only ‘is_correct’ pairs contribute to KL. kl_loss_weight: Multiplier on the aggregated KD term in fixed-weight mode. ce_loss_scale: Multiplier on the next-token CE term in fixed-weight mode. dynamic_loss_scaling: If True, rescale the KD term each step to match the detached CE magnitude;kl_loss_weight/ce_loss_scaleare ignored. kd_loss_mode: How the per-teacher KD terms combine —"sum"(weighted sum),"averaged_logits"(convex-average teacher logits then one KL), or"select_teacher"(use only the lowest-CE teacher). normalize_teacher_by_vocab: sum-mode only — scale each teacher’s KD bylog(V_t_i)/log(min_j V_t_j)so larger-vocab teachers don’t dominate purely by vocab size. alpha: Softmax temperature on the dynamic teacher-weight scores (sum_weights_metric). Inert when weights are static. sum_weights_metric: sum-mode only —"ce"/"entropy"/"max_prob"drives dynamic per-teacher weights;None(default) uses the staticteacher_weights. student_vocab_size: Full student tokenizer vocab size (sizes the projection matrices’ V_s axis). Runtime-injected fromlen(student_tokenizer); not a user YAML knob. teacher_vocab_sizes / projection_matrix_paths / teacher_weights / teacher_gold_loss / teacher_xtoken_loss: Parallel per-teacher lists (one entry perteachers[i]), runtime-injected by the driver from theteachersconfig. ANoneprojection path marks a same-tokenizer teacher (direct KL, no projection / alignment). Not user loss_fn keys in YAML.Initialization
Initialize self. See help(type(self)) for accurate signature.
- gold_loss: bool¶
None
- xtoken_loss: bool¶
None
- temperature: float¶
None
- vocab_topk: int¶
None
- uncommon_topk: int¶
None
- reverse_kl: bool¶
None
- exact_token_match_only: bool¶
None
- kl_loss_weight: float¶
None
- ce_loss_scale: float¶
None
- dynamic_loss_scaling: bool¶
None
- kd_loss_mode: str¶
None
- normalize_teacher_by_vocab: bool¶
None
- alpha: float¶
None
- sum_weights_metric: NotRequired[Optional[str]]¶
None
- student_vocab_size: NotRequired[int]¶
None
- teacher_vocab_sizes: NotRequired[list[int]]¶
None
- projection_matrix_paths: NotRequired[list[Optional[str]]]¶
None
- teacher_weights: NotRequired[list[float]]¶
None
- teacher_gold_loss: NotRequired[list[Optional[bool]]]¶
None
- teacher_xtoken_loss: NotRequired[list[Optional[bool]]]¶
None
- class dockyard_rl.algorithms.loss.loss_functions.CrossTokenizerDistillationLossDataDict¶
Bases:
typing.TypedDictStudent-side keys are fixed; teacher-side keys are teacher-indexed.
Only the student keys below are static. Each teacher
icontributes a dynamic set produced byCrossTokenizerCollator/ the transport and so cannot be enumerated here:Every teacher:
teacher_{i}_full_logits_ipc(node-local CUDA IPC) orteacher_{i}_full_logits_cross_cluster(data_plane) — rebuilt to full-vocab teacher logits by the loss-input keystone.Cross-tokenizer teacher only:
teacher_{i}_input_ids/teacher_{i}_token_mask[B, T_t]andalignment_{i}_*(pair_valid / pair_is_correct / chunk ids / partition masks / num_chunks).Same-tokenizer teacher (
projection_matrix_paths[i] is None): noteacher_{i}_input_ids/alignment_{i}_*; reuses the student tokenization (identity 1:1 alignment).
Initialization
Initialize self. See help(type(self)) for accurate signature.
- input_ids: torch.Tensor¶
None
- input_lengths: torch.Tensor¶
None
- token_mask: torch.Tensor¶
None
- sample_mask: torch.Tensor¶
None
- class dockyard_rl.algorithms.loss.loss_functions.CrossTokenizerDistillationLossFn(cfg: dockyard_rl.algorithms.loss.loss_functions.CrossTokenizerDistillationLossConfig)¶
Bases:
dockyard_rl.algorithms.loss.interfaces.LossFunctionMulti-teacher cross-tokenizer distillation loss.
Each teacher contributes a KD term; the per-teacher terms are aggregated per
kd_loss_modeand combined with a single student next-token CE. The single-teacher path is justnum_teachers == 1.Per-teacher KD path is selected by that teacher’s tokenizer kind and its
(gold_loss, xtoken_loss)flags:Cross-tokenizer teacher (
projection_matrix_paths[i]set):(False, False)-> P-KL: full-vocab projection KL (student logits mapped through the projection matrix M) over a microbatch-global top-k teacher subset.(True, False)-> gold-loss: KL on the exact-mapped common partition plus a sorted-L1 term on the uncommon tail.(True, True)-> gold-loss with the xtoken modifier: relaxed exact-map threshold (>= 0.6) + collision replacement.
Same-tokenizer teacher (
projection_matrix_paths[i] is None): direct top-k per-position KL, no projection / no alignment.
(False, True)is rejected in__init__.Aggregation (
kd_loss_mode):sum(weighted sum; staticteacher_weightsor dynamicsum_weights_metric),averaged_logits(convex-average teacher logits then one KL; same-tokenizer teachers only),select_teacher(use only the lowest-CE teacher).Inputs (via
LossInputType.DISTILLATION_CROSS_TOKENIZER):logits(raw student logits),student_logits_contig(CP-relaid), the per-teacherteacher_full_logits_by_idx(rebuilt by the loss-input keystone) andaligns_by_idx(localized + next-token-shifted per teacher), and the TP/CP groups.Initialization
- loss_type¶
None
- input_type¶
None