Files
wehub-resource-sync e93507a09c
Lockfile supply-chain audit / lockfile supply-chain audit (push) Has been cancelled
Windows Studio GGUF CI / GPU prebuilt resolves without Visual Studio (push) Has been cancelled
Windows Studio GGUF CI / setup.ps1 unit tests (VS 2026 / CMake guard) (push) Has been cancelled
Windows Studio GGUF CI / real-VS detection (VS 2022) (push) Has been cancelled
Windows Studio GGUF CI / real-VS detection (VS 2026) (push) Has been cancelled
Windows Studio GGUF CI / VC++ runtime detect + install round-trip (windows-2025-vs2026) (push) Has been cancelled
Windows Studio GGUF CI / VC++ runtime detect + install round-trip (windows-latest) (push) Has been cancelled
Windows Studio Update CI / Studio Updating Tests (push) Has been cancelled
Wheel CI / Wheel build + content sanity + import smoke (push) Has been cancelled
Lint CI / Source lint (Python + shell + YAML + JSON + safety nets) (push) Has been cancelled
MLX CI on Mac M1 / dispatch (push) Has been cancelled
Security audit / advisory audit (pip + npm + cargo) (push) Has been cancelled
Security audit / pip scan-packages :: extras (push) Has been cancelled
Security audit / pip scan-packages :: studio (push) Has been cancelled
Security audit / pip scan-packages :: hf-stack (push) Has been cancelled
Security audit / npm scan-packages (Studio frontend tarballs) (push) Has been cancelled
Security audit / workflow-trigger lint (pull_request_target / cache-poisoning) (push) Has been cancelled
Security audit / pytest tests/security (push) Has been cancelled
Security audit / npm provenance + new install-script diff (push) Has been cancelled
Studio API CI / Studio API & Auth Tests (push) Has been cancelled
Backend CI / (Python 3.10) (push) Has been cancelled
Backend CI / (Python 3.11) (push) Has been cancelled
Backend CI / (Python 3.12) (push) Has been cancelled
Backend CI / (Python 3.13) (push) Has been cancelled
Backend CI / Repo tests (CPU) (push) Has been cancelled
Frontend CI / Frontend build + bundle sanity (push) Has been cancelled
Studio GGUF CI / OpenAI, Anthropic API tests (push) Has been cancelled
Studio GGUF CI / Tool calling Tests (push) Has been cancelled
Studio GGUF CI / JSON, images (push) Has been cancelled
Mac Studio GGUF CI / OpenAI, Anthropic API tests (push) Has been cancelled
Mac Studio GGUF CI / Tool calling Tests (push) Has been cancelled
Mac Studio GGUF CI / JSON, images (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-14) (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-15) (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-26) (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-15-intel) (push) Has been cancelled
Mac Studio API CI / Studio API & Auth Tests (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-26-intel) (push) Has been cancelled
Mac Studio UI CI / Chat UI Tests (push) Has been cancelled
Studio Tauri CI / Tauri Linux debug build (no codesign) (push) Has been cancelled
Mac Studio Update CI / Studio Updating Tests (push) Has been cancelled
Studio UI CI / Chat UI Tests (push) Has been cancelled
Windows Studio API CI / Studio API & Auth Tests (push) Has been cancelled
Windows Studio UI CI / Chat UI Tests (push) Has been cancelled
Studio Update CI / Studio Updating Tests (push) Has been cancelled
Core / Core (HF=default + TRL=default) (push) Has been cancelled
Core / Core (HF=4.57.6 + TRL<1) (push) Has been cancelled
Core / Core (HF=latest + TRL=latest) (push) Has been cancelled
Core / llama.cpp build + smoke (push) Has been cancelled
Windows Studio GGUF CI / OpenAI, Anthropic API tests (push) Has been cancelled
Windows Studio GGUF CI / Tool calling Tests (push) Has been cancelled
Windows Studio GGUF CI / JSON, images (push) Has been cancelled
Windows Studio GGUF CI / Studio install + inference without Visual Studio (push) Has been cancelled
Studio export capability / capability (macos-latest) (push) Has been cancelled
Studio export capability / capability (ubuntu-latest) (push) Has been cancelled
Studio export capability / capability (windows-latest) (push) Has been cancelled
Cross-platform parity / parity (macos-latest) (push) Has been cancelled
Cross-platform parity / parity (windows-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
Studio load-orchestrator CI / test (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:59:56 +08:00

145 lines
5.9 KiB
Python

# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
"""Completion-only masking policy shared by the CUDA and MLX training paths.
Decides how train_on_responses_only is applied for a model: chat template
auto-detection first, manual TEMPLATE_TO_RESPONSES_MAPPER markers as the
fallback. gpt-oss included: its quantized checkpoints ship a different
chat template, so only detection from the actual template is reliable.
"""
from .model_mappings import (
MODEL_TO_TEMPLATE_MAPPER,
TEMPLATE_TO_RESPONSES_MAPPER,
is_gpt_oss_model_name,
)
def lookup_manual_markers(model_name):
"""Return (template_name, instruction_part, response_part) from the
manual template table, with None parts when the model or template is
not mapped."""
template = MODEL_TO_TEMPLATE_MAPPER.get((model_name or "").lower())
markers = TEMPLATE_TO_RESPONSES_MAPPER.get(template) if template else None
if markers:
return template, markers["instruction"], markers["response"]
return template, None, None
def apply_completion_masking(
trainer,
model_name,
train_fn,
num_proc = None,
notify = None,
detect_fn = None,
):
"""Apply completion-only masking with auto-detection first and the manual
template table as fallback.
Args:
trainer: The platform trainer (SFTTrainer or MLXTrainer).
model_name: Model repo id used for table lookup and the gpt-oss
renamed-checkpoint fallback.
train_fn: The platform train_on_responses_only callable.
num_proc: Forwarded to train_fn when not None (CUDA path only).
notify: Optional callback notify(level, message) with level "info" or
"warning" for user-visible progress and warnings.
detect_fn: Marker detector (tokenizer/processor) -> (instruction_part,
response_part). Defaults to unsloth_zoo's get_chat_template_parts,
which raises loudly when the template cannot be parsed. Test seam.
Returns:
(trainer, applied): the possibly wrapped trainer and whether masking
was applied. When applied is False the trainer is unchanged and
training runs on full sequences.
Only marker DETECTION failures trigger the table fallback. Exceptions
raised while applying the masking (dataset map, tokenization) propagate
to the caller in both the auto and manual paths, so a real failure stops
the run instead of silently changing the training objective.
"""
if notify is None:
notify = lambda level, message: None
kwargs = {}
if num_proc is not None:
kwargs["num_proc"] = num_proc
template, instruction_part, response_part = lookup_manual_markers(model_name)
# gpt-oss goes auto-first: quantized/BF16 checkpoints ship a channel-less
# template, so the manual markers match nothing (zero tokens trained). Auto
# derives markers from whichever template ships, and per the harmony format
# only the final terminator carries stop supervision. Renamed checkpoints
# miss the exact-name table, so give the fallback the gpt-oss markers.
if is_gpt_oss_model_name(model_name) and not (instruction_part and response_part):
markers = TEMPLATE_TO_RESPONSES_MAPPER.get("gpt-oss")
if markers:
template = "gpt-oss"
instruction_part = markers["instruction"]
response_part = markers["response"]
processor = getattr(trainer, "processing_class", None) or getattr(trainer, "tokenizer", None)
# mlx-lm TokenizerWrapper hides underscore attrs, so preset _unsloth_*
# markers are invisible through it. Unwrap to the real tokenizer (as
# zoo's MLX resolver does) before the preset check and detection.
if type(processor).__name__ == "TokenizerWrapper":
wrapped = getattr(processor, "_tokenizer", None)
if wrapped is not None:
processor = wrapped
inner = getattr(processor, "tokenizer", processor)
if hasattr(inner, "_unsloth_input_part") and hasattr(inner, "_unsloth_output_part"):
# Markers preset on the tokenizer; zoo reuses them on a bare call.
trainer = train_fn(trainer, **kwargs)
notify(
"info",
"Train on responses only configured via tokenizer preset markers",
)
return trainer, True
auto_instruction = auto_response = None
try:
if detect_fn is None:
# Torch-backed import is fine: the MLX train_fn itself requires
# unsloth_zoo.dataset_utils, so a torch-free host cannot mask either way.
from unsloth_zoo.dataset_utils import get_chat_template_parts as detect_fn
auto_instruction, auto_response = detect_fn(processor)
except Exception as e:
notify(
"warning",
f"Auto-detection of instruction/response markers failed ({e}); "
f"falling back to the template table",
)
if auto_instruction and auto_response:
trainer = train_fn(
trainer,
instruction_part = auto_instruction,
response_part = auto_response,
**kwargs,
)
notify(
"info",
"Train on responses only configured via chat template auto-detection",
)
return trainer, True
if instruction_part and response_part:
trainer = train_fn(
trainer,
instruction_part = instruction_part,
response_part = response_part,
**kwargs,
)
notify(
"info",
f"Train on responses only configured with template table markers ({template})",
)
return trainer, True
notify(
"warning",
f"'Train on completions' could not be applied for {model_name}: no "
f"auto-detected or mapped instruction/response markers. Training "
f"will run on full sequences (prompts included).",
)
return trainer, False