Skip to content

v0.12.1: Unsloth 2026.9.2 / vLLM 0.28.0 images validated on Qwen3.8-27B and the full cookbook; DPO, GPU-reclaim and API-deploy fixes; training diagnostics - #81

Merged
nielsrolf merged 12 commits into
mainfrom
codex/training-validation
Sep 7, 2026
Merged

v0.12.1: Unsloth 2026.9.2 / vLLM 0.28.0 images validated on Qwen3.8-27B and the full cookbook; DPO, GPU-reclaim and API-deploy fixes; training diagnostics#81
nielsrolf merged 12 commits into
mainfrom
codex/training-validation

Conversation

@nielsrolf

@nielsrolf nielsrolf commented Sep 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Worker images rebuilt and released (v0.12, then v0.12.1). Unsloth 2026.9.2 on Torch 2.10.0+cu128 / Transformers 5.5.0 / TRL 0.24.0; vLLM 0.28.0 on Torch 2.13.0+cu130 / Transformers 5.16.1. Dependencies are resolved together and pip check is enforced. Unused MergeKit/LLM Blender dropped from the Unsloth image. SDK defaults and package version are now v0.12.1 / 0.12.1. Release tags are thin overlays on the GPU-validated candidates, so pip freeze is byte-identical (results/image-freeze-*.txt).
  • Qwen/Qwen3.8-27B validated on GPU: SFT ftjob-a14928964512, DPO ftjob-18fa65aeea16, inference inferencejobs-56262ef4e688. v0.11 failed at load.
  • Full integration suite run (tests/test_integration.py, Docker build-and-push skipped so it cannot overwrite validated tags; new --skip flag): signup/tokens passed, local worker passed, all 15 cookbook examples passed (SFT on Qwen3.5-0.8B, Qwen3-4B, Gemma 3 4B, OLMo 3 7B, Qwen3.5-35B-A3B, QLoRA Llama 3.3 70B; logprob tracking; sampling callback; token-weighted SFT; Llama 3.1 8B DPO and ORPO; batch inference; Qwen3.6-35B-A3B inference; custom job; API deployment).

Bugs fixed (each found by a real failure in this PR's validation)

  1. DPO on Qwen3.5/Qwen3.8 crashed after loading. TRL 0.24 flags model_type=qwen3_5 as a vision model and tokenizes preference rows through processing_class.tokenizer. TextPreferenceDPOTrainer uses text tokenization when given a plain tokenizer. Also: DPO now passes the normalized LR, max_length and eval schedule to DPOConfig.
  2. Worker GPU reclaim caused unbounded pod churn. reclaim_gpu treated any GPU-holding PID outside the container as fatal. RunPod hosts commonly expose a host-side process holding ~700 MiB: a single inference job spun up 88 H100 NVL pods in two hours without ever running (~3.45 pod-hours), and 9 of 13 H200 pods did the same during the smoke tests. Foreign holders are now ignored while min_free_fraction is met. Shipped as v0.12.1 because worker code is baked into the images. Follow-up: the cluster manager has no back-off when workers fail before running a job.
  3. ow.api.deploy() crashed unless OPENAI_API_KEY was set. TemporaryApi.up() built OpenAI clients with api_key=None. Now reads the key from job params like the async path.
  4. Inference CLI: removed the deleted snapshot_download(local_dir_use_symlinks=...) argument. validate.py accepts adamw_torch.

Also included

  • Rebuilt dashboard frontend assets for the merged PRs (Fix dashboard option page #73, Fix password reset flow: add missing /reset-password route #46); committed with --no-verify like previous builds.
  • Training diagnostics (experiments/training_comparison/): OpenWeights vs Tinker on Qwen3-8B with deterministic data, shared evaluation masks, two seeds, an LR sweep, a 128/128 trainer/collator label audit, an adapter-metadata audit and an alpha-32 control. OW and Tinker match closely at LR 1e-4 and 1e-3; at 1e-5 OW learned much more slowly (test NLL 4.17 vs 0.89). Tinker's adapter uses lora_alpha=32 vs OW's 16; an OW alpha-32 control roughly halves the log-NLL gap but does not close it. Remaining confounds are documented, not resolved. See REPORT.md, STATUS.md, LARGE_MODELS.md (GLM-5.3-scale training needs a sharded backend; the native trainer is single-device).

Validation

  • 36 unit tests pass; formatting hooks pass.
  • results/image-validation.json has digests, job IDs and per-example integration results; results/integration-worker-accounting.json has pod-hours.
  • Cluster image v0.12.1 passes its build-time runtime check but was not redeployed.

Not included

🤖 Generated with Claude Code

nielsrolf and others added 12 commits September 5, 2026 02:08
- Base the Unsloth image on pytorch/pytorch 2.10.0-cu128, resolve the SDK and
  worker dependencies together, and require pip check. Drop unused MergeKit
  and LLM Blender whose safetensors pin conflicts with current Unsloth.
- Pin vLLM 0.28.0, Transformers 5.16.1, TRL 0.24.0 and a FastAPI range that
  matches vLLM; require pip check.
- Remove the deleted snapshot_download(local_dir_use_symlinks=...) argument
  from the inference CLI (removed in huggingface-hub 1.x).
- Document candidate validation before promoting a tag.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Adds the seed-17 learning-rate sweep, the native trainer/collator label
audit, the Tinker adapter metadata audit and an OpenWeights alpha-32
control at 1e-5, plus collection scripts, figures, REPORT/README/STATUS and
a large-model assessment. The alpha-32 control roughly halves the log-NLL
gap to Tinker at 1e-5 but does not close it; remaining confounds are
documented rather than resolved.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Generated bundle; the large-file hook is bypassed for these assets as with
the previously committed builds.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
TRL 0.24 marks any model whose model_type is in the image-text-to-text
mapping (Qwen3.5/Qwen3.8, Qwen3-VL) as a vision model and tokenizes
preference rows through processing_class.tokenizer, which only exists on a
processor. OpenWeights preference data is text-only and the trainer receives
the unwrapped tokenizer, so DPO on Qwen/Qwen3.8-27B crashed after loading
(ftjob-7ea5a20e14fc). TextPreferenceDPOTrainer falls back to TRL's text
tokenization whenever it is given a bare tokenizer. Verified by
ftjob-18fa65aeea16 on the v0.12 candidate image.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Promote the GPU-validated v0.12 candidates (Unsloth 2026.9.2 / vLLM 0.28.0)
to nielsrolf/ow-unsloth:v0.12, ow-vllm:v0.12 and ow-cluster:v0.12, and point
the SDK defaults and package version at them. Release tags are overlays on
the candidates that refresh only the SDK source and metadata; pip freeze is
unchanged. Document the promotion procedure.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
SFT, DPO (failed first attempt and fixed rerun) and inference smoke tests on
one H200 each, image digests and dependency freezes, worker accounting, and
the observed worker churn caused by foreign GPU holders on RunPod hosts.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
test_docker_build_and_push rebuilds and pushes the production image tags
from openweights/images.py, which would overwrite already validated images.
Allow skipping it (or any test) without the --skip-until state file.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…12.1

reclaim_gpu raised ForeignGpuHolderError for any GPU-holding PID outside the
container regardless of how much memory it held, and the worker then
reverted its job and shut down. RunPod hosts commonly expose a host-side
process holding ~700 MiB: during the integration suite all 88 one-GPU H100
NVL pods provisioned for a single inference job did this in a loop for two
hours (about 3.45 pod-hours wasted, job never ran), and 9 of 13 H200 pods
did the same during the Qwen3.8-27B smoke tests.

Ignore foreign holders while the GPU still meets min_free_fraction and only
fail when a foreign holder actually occupies the card. Ship as v0.12.1
because worker code is baked into the images; the release tags are overlays
on the validated v0.12 candidates with an unchanged pip freeze.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
TemporaryApi.up() never set self.api_key, so the sync and async OpenAI
clients were constructed with api_key=None and the OpenAI SDK raised
'Missing credentials' unless OPENAI_API_KEY happened to be set. The
deployment itself had already come up. Read the key from the job params as
async_up() does, and use it for the readiness probe too.

Found by cookbook/api-deployment/context_manager_api.py in the integration
suite.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signup/tokens and local worker execution passed; Docker build-and-push was
skipped deliberately; all 15 cookbook examples passed (13 on v0.12, the
Qwen3.6-35B-A3B inference, custom job and API deployment examples on v0.12.1
after the GPU-reclaim and TemporaryApi fixes). Includes pod-hour accounting
for the integration-test organization.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@nielsrolf nielsrolf changed the title v0.12: Unsloth 2026.9.2 / vLLM 0.28.0 images validated on Qwen3.8-27B, DPO fixes, training diagnostics v0.12.1: Unsloth 2026.9.2 / vLLM 0.28.0 images validated on Qwen3.8-27B and the full cookbook; DPO, GPU-reclaim and API-deploy fixes; training diagnostics Sep 6, 2026
@nielsrolf
nielsrolf merged commit ab126ac into main Sep 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant