msuiche/weightless

Abliteration without the weights — projective refusal steering as a GLP vector + fail-closed boot hotfix.

Python

86

322 commits

updated Oct 18, 2026

See the code

See what people are saying

SourceMessageScoreDate

Uncensored models via LORA (r/LocalLLaMA)

I know the heretic tool is the usual generic approach to remove refusals from a model, and a lot of research has been done to find out what parts in the LLM need to change. This gets very expensive though the larger the model is. Then for Krea2 turbo/base I saw that there are LORAs to remove…

25

Oct 17, 2026

Abliteration Without the Weights

2

Aug 23, 2026

README

weightless feather logo

weightless

Abliteration without the weights — put your model on GLP. Projective refusal steering for open-weight models: serving config, boot hotfixes, the steering patch, and the GLP (GGUF Layer Projection) format spec. The goal is most good open models; the lanes are DeepSeek V4 Flash 0731 on 2x DGX Spark (GB10, SM121, TP=2 over RoCE), Qwen3.8-27B on a single Spark, Qwen3.8-Flash-Next NVFP4 on 2x DGX Spark (TP=2, day-0 image), and GLM-5.3-Flash NVFP4 on 4x DGX Spark (TP=4, patched day-0 image), and GLM-5.3 743B Int4-Int8Mix on 4x DGX Spark (TP=4, tonyd2wild's recipe). The method and the measurements behind it are in the original write-up: Abliteration without redistributing the model.

The live DSV4 stack is the Anemll image (ghcr.io/anemll/dspark-vllm-gx10:0.1.1, vLLM 0.25.2) driven by the MiaAI 2x recipe, with our state on top vendored in recipe/anemll/; the Qwen lane (stock vLLM 0.27 image, GGUF or LoRA steering) lives in recipe/qwen/; the Qwen3.8-Flash-Next lane (day-0 image vllm/vllm-openai:qwen38-flash-next, GLP-47) lives in recipe/qwen38fn/; the GLM-5.3-Flash lane (tonyd2wild's sm121-v8 patch stack on the day-0 vllm/vllm-openai:glm53-flash-arm64-cu130, GLP-44) lives in recipe/glm53/; the GLM-5.3 743B lane (tonyd2wild's Int4-Int8Mix stack, GLP-77) lives in recipe/glm53xl/. The retired v027 stack's patch is kept for reference and as the fallback path.

setup wizard — splash, local-state box, main menu

Quick start

python3 weightless.py          # the one front door — interactive setup wizard
python3 weightless.py serve 0  # switch the rig to a lane, no prompts (serve <name|#>)
python3 weightless.py dash     # live metrics for the serving lane
python3 weightless.py test     # endpoint smoke suite
python3 weightless.py --help   # all commands

weightless.py (Python 3.9+, stdlib only) dispatches to the real scripts, which also work standalone: setup.py (TUI wizard with a prompt fallback), scripts/dash.py, tests/smoke/run.sh.

Use python3 weightless.py help <command> for command-specific options. python3 weightless.py setup --plain uses text prompts; setup requires an interactive terminal. With redirected stdin, invoking weightless.py without arguments prints help. serve rejects unknown flags before deployment; omit its lane argument to list available lanes.

For scripts, python3 weightless.py dash <url> --once --timeout 5 prints a snapshot (two samples --interval apart, so its rates are real) and exits nonzero if the endpoint fails or returns no vLLM metrics; --json prints the same numbers as one JSON object. Dashboard URLs may include /v1 or /metrics. Refresh intervals, rate windows and request timeouts must be positive and finite. Redirected dashboard output contains no terminal control sequences; NO_COLOR disables colors in both prompts and the dashboard. In the live view q quits, p pauses, r resets the session counters and w cycles the rate window (10 / 30 / 60 / 300s).

Swapping lanes is the wizard, not ssh. Pick Serve <model> for the lane you want: the wizard regenerates the env, re-validates it (multi-node fabric addresses must be literal IPs — containers cannot resolve .local; the steering vector's glp.hook_point is read on the node and must match the lane's enforced site), parks the running lane's containers, drops page caches, boots, then reconfigures omp/hermes and runs the smoke suite. If a swap ever needs a manual ssh incantation, that gap goes into the wizard — not into shell history.

Pick a lane and it walks the full chain: site values → env file → steering validation → asset preparation → confirm-gated ssh deploy → omp provider (registered in omp's modelRoles — default role, or every text role) + endpoint smoke tests. Endpoint down? The diagnose chain isolates DNS → TCP → HTTP and can check and boot the stack over ssh. Non-interactive alternative: sh tests/smoke/install.sh && sh tests/smoke/run.sh with DSPARK_* env overrides.

Asset preparation downloads the model on the head, rsyncs its HF cache to workers over the fabric, pulls the recipe image on each node, and downloads the selected GLP file on every node. Each command is printed and confirmed; downloads resume on reruns. Set HF_TOKEN or use hf auth login locally after accepting access to the gated vector repository. The token travels over SSH stdin and is never printed. Remote HF tooling uses its own venv (nodes need Python 3 with venv support). GLM 743B still requires the recipe's local image build, kernel overlay and mounted weight directories; the wizard verifies that image instead of attempting to pull a nonexistent registry tag. Before boot, switching lanes offers a separate, default-no confirmation to remove the old lane's containers on its nodes and prints the relaunch command. DEMO=1 python3 setup.py skips writes, downloads and all network commands.

What this is: lean abliteration steering as a patch

The model weights are never redistributed — what this repo ships is the intervention, tested and self-contained:

  • The steering file. A GLP vector — a spec-conformant control-vector GGUF (docs/spec/GLP.md) with per-layer directions, derived by us and published under msuiche/ (see Steering artifacts). No model weights inside.
  • The patch. The installable plugin (vllm-plugin/, dist weightless-steer): one adapter per architecture in weightless_steer/archs/ shadows the model class in vLLM's ModelRegistry, installing the same projective hook with no container file rewrites at all — ten archs, every one GPU-validated on Modal (2026-09-18/19, per-lane numbers in BENCHMARK.md). The boot hotfixes (patches/hotfix-*.py) are the per-lane mechanism the plugin replaces: still what the live rigs run today, kept as the fallback stack and as the semantic reference each adapter is pinned against by structure tests (tests/structure/, vllm-plugin/tests/).
  • Quant-friendly. The hook steers activations at runtime (the calibrated site per lane: post-layer residual where the runtime materialises it, the pre-fold FFN write on the DSV4 lane, 2026-09-04 site correction), so it works on quantized checkpoints (NVFP4 verified on both lanes, bf16→NVFP4 transfer measured) as long as the base architecture is intact. The one exception is REAP-pruned builds: deleting experts changes the shape of the base model, the vector no longer matches the circuit, and the lane is rejected on those grounds (see Lanes).
  • A no-patch option for Qwen. The same intervention folded into a rank-1 LoRA we reproduced — it loads in stock vLLM/peft with no hotfix at all and matches the GGUF arm on hardware (both 24/32 refusal32).

Internals write-up: Abliteration without redistributing the model.

Streams and writers — and why GLP is not a LoRA

Two objects get confused often enough that GLP ends up misfiled as a LoRA variant. They are different objects, and the difference is the whole design:

  • The residual stream is the running sum a token carries through the network: the embedding output plus everything every layer has added so far. It is an activation — it exists only at runtime, and no single weight matrix sits behind it. A behavioral direction "in the residual stream" means a direction in that accumulated quantity.
  • A residual writer is one of the matmuls whose output gets added into the stream: self_attn.o_proj, mlp.down_proj (linear_attn.out_proj on hybrid archs). Each writer has a concrete W you can read and edit.

GLP's native object is a direction d̂ in the stream, and its native operation projects the accumulated stream at runtime: h ← h − α(h·d̂)d̂, applied by a hook after each listed layer. Activation space, α tunable at serve time, architecture-blind, nothing re-baked.

A LoRA can only express a weight delta ΔW = B·A on an existing matmul. "Project the stream" has no single W behind it, so it cannot be written as a LoRA. What can be written is "project each residual writer": at h = Wx the projection is exactly ΔW = −α·d̂(d̂ᵀW) — the Arditi et al. weight-orthogonalization form, which is what captain-vector bake emits as a rank-1 adapter. Every limitation of the baked form follows from that one substitution:

  • Writer ≠ stream. Projecting all of a layer's writers at α equals projecting that layer's new contributions at α (linearity) — but a d̂-component already riding the incoming stream (embeddings, an unbaked writer) passes through, where the runtime hook removes it regardless of origin. Close in practice, not bit-identical.
  • Dense-only in practice. On MoE the writers are per-expert — hundreds of matrices per layer — so a bake explodes into thousands of rank-1s against quantized weights. Runtime stream steering is architecture-blind; the MoE lanes here (DSV4, GLM, Hy4, K3) exist because of it.
  • α is frozen into lora_A — not tunable at serve time, and scaling the adapter double-doses.
  • Checkpoint-bound. lora_A carries W; baked against the wrong base revision the adapter is garbage and nothing downstream flags it (bake's pin check fails closed for exactly this reason).

The same constraint runs the other way: llama.cpp control vectors and the steering-LoRAs that circulated before GLP are addition-only (h ← h + scale·d), and addition cannot express "remove the d̂-component of whatever passes through here" — nor bake exactly anywhere (a constant shift is a bias, not a weight delta). Add-vs-project and runtime-vs-baked are two independent axes. GLP occupies the projective, runtime-native quadrant; the baked adapter is its portable shadow for stacks that only speak LoRA.

Deeper: FAQ.md (answers to the questions people actually ask — backdoor auditability, vector maintenance under retraining, effective range, MoE/loop coverage, dosage, termination), docs/spec/GLP.md (the format contract), docs/llama-cpp-compat.md (source-verified mechanics), tools/captain-vector/README.md (bake's troubleshooting/interop role).

The stack

Serving is vLLM (the only runtime with working sm_121a NVFP4 + MTP paths for these checkpoints on GB10), driven by omp as the agent harness/client — we picked it over stock Pi for the benchmaxxed tool loop (hash-anchored edits, LSP/DAP wired in, fast headless mode), and this repo's tests/ suite proves the served model can drive it end to end. Steering is optional per lane and off by default when the steer path is empty:

flowchart LR
    subgraph client[client]
        OMP["omp<br/>agent harness"]
        WIZ["setup.py<br/>wizard + tests/"]
    end
    OMP -->|OpenAI-compatible /v1| EP["vLLM endpoint<br/>:8888, :8078, :8079, :8080 or :8081"]
    WIZ -->|probe / diagnose / boot| EP
    EP --> DSV4["DSV4 lane — TP=2<br/>2x DGX Spark over RoCE<br/>DeepSeek-V4-Flash-0731 NVFP4"]
    EP --> QWEN["Qwen lane — TP=1<br/>single DGX Spark<br/>Qwen3.8-27B NVFP4"]
    EP --> QWENFN["Flash-Next lane — TP=2<br/>2x DGX Spark over RoCE<br/>Qwen3.8-Flash-Next NVFP4"]
    EP --> GLM["GLM-5.3-Flash lane — TP=4<br/>4x DGX Spark over RoCE<br/>GLM-5.3-Flash NVFP4"]
    CV["GLP vector (GGUF)<br/>fail-closed boot hotfix"] -.->|optional| DSV4
    CV2["GLP vector hotfix<br/>or rank-1 LoRA, no patch"] -.->|optional| QWEN
    CV3["GLP-47 vector (GGUF)<br/>fail-closed boot hotfix"] -.->|optional| QWENFN
    CV4["GLP-44 vector (GGUF)<br/>fail-closed boot hotfix"] -.->|optional| GLM
    EP --> GLMXL["GLM-5.3 743B lane — TP=4<br/>4x DGX Spark over RoCE<br/>GLM-5.3 Int4-Int8Mix"]
    CV5["GLP-77 vector (GGUF)<br/>staged fail-closed hotfix"] -.->|optional| GLMXL

The lanes never run at once: each multi-node lane (DSV4 on 2, Flash-Next on 2, the GLM lanes on 4) already holds its Sparks' GPUs, and the Qwen lane is parked until the multi-node stack is down.

endpoint smoke tests running inside the wizard

Lanes

lanehardwaremodelsteeringstatus
DSV4 TP=2both Sparks over dual-rail RoCEDeepSeek-V4-Flash-0731, NVFP4 (166.9 GB)projective cvec, live on 29 layerslive — recipe/anemll/
DSV4-Vision-Exp TP=2both Sparks over dual-rail RoCEDeepSeek-V4-Flash-Vision-Exp, FP8 original (202 GB)projective cvec, L10–38 at α=1.0 (the -ffn hook relabel of GLP-29 Vision-Exp)live (text-only) — the 0.25.2 image's loader refuses the checkpoint's vision.*/aligner tensors, so this lane serves the vision-stripped FP8 tree (strip_vision.py output, staged at $HF_CACHE/visionexp-text-fp8); recipe/anemll/ (.env.dsv4vx + start-deepseek-v4-flash-visionexp-dspark.sh). Vision-capable serving is the VL lane below
DSV4-Vision-Exp VL TP=2both Sparks over dual-rail RoCEDeepSeek-V4-Flash-Vision-Exp, FP8 unstripped (snapshot 6821d6ad, vision enabled)same -ffn GLP-29 relabel, L10–38 at α=1.0 (day-0 tree keeps the deferred mHC fold → ffn_out_pre_residual)first-boot-validated 2026-09-23 (2x DGX Spark, GB10) — recipe/dsv4vl/; day-0 vLLM (0.28.1rc1 + PR #54566) on vllm-upstream-vision:k2-topk512 (flashinfer 0.6.18 + DSV4 dual-prefill topk 192/256/512 backport, msuiche/flashinfer); nospec; cold boot 8m24s; steering A/B green (α=0.0 base-like, α=1.0 cyber 4/4 comply, benign 4/4 both arms, ~13.4 tok/s single-stream both arms); vision smoke under steering green (image-token math 315∈[314,317], 111∈[110,113], mix, text-only, concurrency)
Qwen TP=1one SparkQwen3.8-27B-NVFP4 (~13.5 GB)per-layer cvec, L10–58 at α=1.0 (shipping artifact)hardware-validated — recipe/qwen/; stock 4/32, GGUF 24/32, LoRA 24/32 on refusal32 (2026-08-22)
Qwen3.8-Flash-Next TP=2both Sparks over RoCEQwen3.8-Flash-Next-NVFP4 (~135 GB), day-0 imageper-layer cvec, L1–47 at α=1.0 (GLP-47)hardware-validated 2026-09-01 (2x DGX Spark, GB10) — recipe/qwen38fn/; steered live on the pair: refusal32 22/32 (stock 1/32), KV pool 35.3 GiB @ 262K native ctx; earlier cloud validation (2xB200): refusal32 1/32 → 26/32, benign 32/32; vector eval 81.2% refusal32 (vLLM lane, cos 0.9931 vs HF)
DSV4-Vision-Exp (Modal lane)4×H100 (tolmo)DeepSeek-V4-Flash-Vision-Exp, FP8 (~168 GB)per-layer cvec, L10–38 at α=1.0 (GLP-29 Vision-Exp)vector-validated 2026-09-01 — refusal32 1/32 → 27/32 fresh (α=4 garbles — dose cliff), benign32 32/32 both arms; the 0731 GLP-29 keysdir vector transfers at 31/32 despite cos −0.32 (multi-directional refusal); Spark lane: the TP=2 row above
DSV4-Vision-Exp NVFP42×B200 (tolmo)msuiche/DeepSeek-V4-Flash-Vision-Exp-NVFP4 (176.5 GB, modelopt W4A4, experts-only)same GLP-29 vectorsboot-validated 2026-09-03 (stock vLLM 0.28.0, first vLLM boot of vision-exp) — lossless MXFP4→NVFP4 transcode (byte-exact vs NVIDIA's recipe); NVFP4 ≈ FP8 ±1 item on refusal32, benign 32/32, capability 12/12, zero garbles; steered-delivery delta vs the old HF-lane numbers is a lane effect (fp8 KV + kernels), not the quant — FP8 control lands the same; strip_vision.py in-repo for stock-vLLM text boot; GB10 via modelopt_gb10_hybrid plugin
Inkling-Small TP=2both Sparks over RoCEInkling-Small-NVFP4 (159 GiB), stock vLLM 0.28.0, CUDA graphs onper-layer cvec, L1–41 at α=0.25 (GLP-41)hardware-validated 2026-09-04 (2x DGX Spark, GB10) — recipe/inkling/; real weights boot and serve with the load-reclaim + sm121 rel-attention hotfixes (78.3 GiB model, 21.4 GiB KV, 4/4 smoke); Modal lane: refusal32 0/32 stock (total lockdown) → 30/32 steered, benign32 30/32; α=1.0 garbles everything — the most dose-sensitive model in the program; first GLP for a Thinking Machines model
Hy4-preview (Modal lane)8×H200 (tolmo)tencent/Hy4-preview-FP8 (770B / 49B active, ~770 GB), day-0 imageper-layer cvec, L1–77 at α=2.0 (GLP-77 Hy4)vector-validated 2026-09-02 — refusal32 1/32 → 24/32, cyber32 15/32 → 31/32, benign32 32/32 at α=2.0 (collateral non-monotonic: worst at α=1.0–1.5, zero at full dose); no garble at any dose — most steer-tolerant arch in the program; largest model with a published refusal vector; caveat: refusal32 answers all run to the 4K cap at α=2.0
GLM-5.3-Flash TP=4four Sparks over RoCEGLM-5.3-Flash-NVFP4 (~50 GiB/rank), othexmr's RiNGSiDE recipe (switchless ring NCCL + b12x kernels; previously the sm121-v8 patched day-0 image)per-layer cvec, L1–44 at α=2.0 (GLP-44)live in production since 2026-09-29 — recipe/glm53/; 1M context, 36 tok/s freeform → 53–64 tok/s structured/agentic with DFlash2 spec decode (acceptance is regime-dependent; steering costs none — measured, see below); vector eval 65.6% refusal32 at α=2.0; α≥2.5 garbles this model
GLM-5.3 743B TP=4four Sparks over RoCEGLM-5.3 Int4-Int8Mix (~95.5 GiB/rank), tonyd2wild's stack (local image + sm12x overlay)per-layer cvec, L1–77 at α=1.0 (GLP-77)hotfix live-validated 2026-08-30 — recipe/glm53xl/; on stock vLLM 0.28.0 (8×H100, RadixArk/GLM-5.3-NVFP4): refusal32 1→10/32, cyber32 15→31/32; the 4x-Spark GB10 lane itself remains untested (needs the hardware); vector eval (8×H100, full-length): cyber32 32/32, refusal32 12/32 (37.5%; 6/32 answer-audited) at α=1.0, null arm = stock; refusal on the 753B is much stickier than Flash — α>1 makes it WORSE
GLM-5.3 743B cloud (Modal lane)8×H100, wizard-deployedRadixArk/GLM-5.3-NVFP4 (~465 GB), stock vLLM 0.28.0same GLP-77, α=1.0deployable — modal/cloud_serve.py; delivers an OpenAI-compatible endpoint, no rig needed
Kimi K3 2.9T cloud (Modal lane)2×H200:8 (PP=2 x TP=8, TCP fabric), wizard-deployedmoonshotai/Kimi-K3 (~1.56 TB, MXFP4 experts), day-0 imageper-layer cvec, L1–92 at α=1.0 (GLP-92)vector-validated 2026-09-04 — refusal32 1/32 → 31/32, cyber32 17/32 → 32/32, zero collateral (benign32 32/32, propaganda32 32/32); modal/cloud_serve_k3.py: collective lockstep serving (the fork's multi-node serve shape wedges), deploys to an OpenAI-compatible endpoint

GLM-5.3-Flash needs 4 nodes — and a patched image. At TP4 the NVFP4 quant is ~50 GiB of weights per 128 GB node, which is what makes the 1M-context KV pool possible. Since 2026-09-29 the production lane runs othexmr's RiNGSiDE (switchless ring NCCL, b12x kernels, RDMA prefill, DFlash2 drafting; TP2 and TP4 profiles) with the GLP-44 steering mounted via its weightless launcher option. A 2-node TP2 config exists (262K context, KV-starved — tonyd2wild's TP2 repo) but stays out of scope for this wizard lane. The stock day-0 vendor image dies five different ways on GB10; the lane requires the sm121-v8 patch stack (radixark/vllm-glm53-flash:sm121-v8 or a local v1→v8 build — details in recipe/glm53/README.md). If your machines.txt lists two nodes, this lane cannot boot until two more are racked and cabled. The 743B lane needs the same four nodes plus tonyd2wild's Int4-Int8Mix weights (377.4 GiB) and stack (image + kernel overlay — recipe/glm53xl/README.md); its first real boot is the anchor test (the hotfix stages fail-closed before GPU time). On x86 SM120 instead of Sparks, brandonmusic's EXL3/B12X build (brandonmusic/GLM-5.3-Flash-tr3-4bpw, custom vLLM fork) takes the same GLP-44 hotfix mechanics — see recipe/glm53/README.md (runtime-validated on 2x RTX PRO 6000: refusal32 1→15/32, cyber32 14→31/32).

DFlash2 spec decode and steering — measured, not assumed (2026-08-30, 4xH100, Prometheus spec_decode counters): GLP-44 steering at α=2.0 costs the drafter no acceptance — structured 81.4% → 87.1% steered, prose 26.1% → 24.4% — because the drafter's aux-capture taps sit before the steering injection point and condition on pre-steering features. The stock tap set [5,14,24,33,42] ships in the drafter's own config.json and is training-matched: a 7-set sweep found every alternative worse, tapping the final target layer poisons the drafter (~6% acceptance), and the tap count is fixed by the checkpoint's fc width. Prose acceptance (~26% Flash, ~23% flagship) is a drafter-capacity limit, not a tap-tuning opportunity — do not retune the taps.

Single-Spark DSV4 (EXL3 3.0bpw + REAP-K216): evaluated and rejected. The full NVFP4 checkpoint (166.9 GB) cannot fit one Spark, so single-node DSV4 exists only as the pruned/quantized artifact — REAP deletes 40 of 256 routed experts per MoE layer on top of the 3.0bpw quant. Benchmarks pass, but the degradation concentrates in rare behaviour by construction, and the control vector would need re-deriving on the pruned circuit. TP=1 DSV4 is a smaller, approximated model; we do not serve it. The steering contract in docs/spec/GLP.md remains lane-independent.

Layout

pathwhat it is
weightless.pysingle front-door CLI: weightless.py (wizard), weightless.py dash, weightless.py test, `weightless.py validate
setup.pyfull-chain setup wizard (TUI or prompts, stdlib-only): lane pick → env file → steering validation → ssh deploy → omp provider + tests, plus a diagnose chain (DNS → TCP → HTTP → remote docker/GPU status, optional boot)
recipe/anemll/live: compose / start script / .env.dsv4.example for the MiaAI 2x clone, plus rebuild notes
recipe/qwen/Qwen TP=1 lane: serve script + .env.qwen.example; STEER_MODE=gguf|lora, both hardware-validated
recipe/qwen38fn/Qwen3.8-Flash-Next TP=2 lane: head+worker start script + .env.qwen38fn.example; --no-enable-prefix-caching and VLLM_PLE_CPU_OFFLOAD=1 are mandatory there
recipe/glm53/GLM-5.3-Flash TP=4 lane: head+3-worker start script + .env.glm53.example; needs 4 nodes and the sm121-v8 patched image, α=2.0 is calibrated (α≥2.5 garbles)
recipe/glm53xl/GLM-5.3 743B TP=4 lane: head+3-worker start script + .env.glm53xl.example; needs 4 nodes + tonyd2wild's Int4-Int8Mix weights/stack, α=1.0 is calibrated (higher makes refusal worse)
patches/hotfix-dsv4-steering-projective.pylive: steering as a fail-closed boot hotfix for the 0.25.2 image (embedded GGUF reader)
patches/hotfix-qwen38-steering-projective.pythe same steering for the Qwen lane: patches qwen3_next.py + qwen3_5.py, steers hidden_states + residual
patches/hotfix-qwen38fn-steering-projective.pythe same steering for the Flash-Next lane: patches the day-0 image's vllm/models/qwen3_8_flash_next/nvidia/model.py, steers the materialized hyper-connection stream (10240 = 4×2560)
patches/hotfix-glm53-steering-projective.pythe same steering for the GLM-5.3 lane: patches vllm/models/glm5next/nvidia/model.py, steers the materialized mHC stream (16384 = 4×4096); the last layer's in-decoder contract is deferred so L44 is covered
patches/hotfix-glm53xl-steering-projective.pythe same steering for the GLM-5.3 743B lane: patches the overlay's deepseek_v2.py copy at staging (the mount is read-only), steers hidden_states + residual (decomposed convention, no HC widening)
patches/hotfix-glm53-exl3-steering-projective.pythe GLM-5.3-Flash steering for brandonmusic's EXL3/B12X fork image (SM120): the fork's DFlash branch splits the decoder loop in two — the variant patches both (aux loop steers after the aux capture, pre-steer features)
vllm-plugin/the same steering as an installable vLLM plugin (dist weightless-steer, vllm.general_plugins entry point): one adapter per architecture in weightless_steer/archs/ shadows the model class in ModelRegistry instead of rewriting files in the container — the successor to the hotfix fleet above. Ten adapters today: nemotron_h.py, glm5next.py, dsv4.py, qwen38.py, qwen38fn.py, glm53xl.py, kimi_k3.py, ouro.py, inkling.py, hy4.py. glm5next GPU-validated 2026-09-18 (Modal 4×H100, GLM-5.3-Flash NVFP4, compiled mode — cyber32 31/32 exactly the hotfix reference, benign32 clean, refusal32 2→9/32 vs 1→21/32 hotfix on a stiffer stock baseline; modal/cloud_serve_glm53.py); the other eight new adapters GPU-validated 2026-09-19 on Modal (verification depth varies — full eval for dsv4/qwen38/qwen38fn/ouro/inkling, boot+smoke for hy4/glm53xl/kimi-k3; per-arch numbers in BENCHMARK.md, raw artifacts in modal/out-<arch>-plugin-test/). Design: docs/vllm-plugin-design.md, offline tests need neither GPU nor vLLM
sglang-plugin/the same steering as an installable SGLang plugin (dist weightless-sglang, sglang.srt.plugins entry point): an AFTER hook on ModelRunner.load_model installs the steering sites before CUDA-graph capture, with no SGLang source change, and reuses the vLLM plugin's loader and gates. One module per architecture in weightless_sglang/archs/: Qwen3.8-27B (one RTX 5090) and GLM-5.3-Flash (3x RTX PRO 6000, PP 3) GPU-validated 2026-09-25/26, seven more structure-tested on CPU. The edit runs as one fused Triton kernel by default, self-checked at start-up against a torch path that gives the same bits. Design: docs/sglang-plugin-design.md; offline tests need neither GPU nor SGLang
patches/vendor/sparse_attn_indexer_kpool_sm121.pyvendored SM121 indexer top-k fix (tonyd2wild's DFlash2 repo, provenance header inside): bind-mounted over the in-image file on every glm53 node — without it both published images hard-kill on decode past ~24K context
patches/reference/glm5next_b12x_exl3.pythe EXL3 structure test's reference — the model file extracted from the published verdictai/glm53-flash-exl3-k4 image (OCI layer sha256:7f03081e…)
patches/reference/deepseek_v2_glm53xl.pythe 743B structure test's reference — tonyd2wild's kernel-overlay deepseek_v2.py (the file his stack actually serves); same anchors as vLLM v0.28.0
patches/reference/qwen3_8_flash_next.pybyte-identical copy of the day-0 image's model file — the Flash-Next structure test's reference (the ../vllm checkout predates the arch)
patches/reference/glm5next.pythe GLM-5.3 structure test's reference — from the day-0 PR source (vllm-project/vllm#53906); re-vendor against the image on first deploy
patches/0001-*.patch, 0002-*.patchthe hook + its vLLM-side test as git patches against v0.27.0 (fallback stack)
recipe/ (top level)retired v027 stack: Dockerfiles + compose
tests/structure/structural guard tests for the steering patches (test-*-structure.py, incl. test-steering-structure.py for the retired v027 overlay)
scripts/dash.py (below), dspark-router.py, memory-watchdog-gpu.sh, probe-refusal.py
scripts/dash.pylive terminal view of any serving lane (stdlib only, ANSI colors on a terminal — brand pink/cyan, KV gauge green→yellow→red; --no-color/NO_COLOR for plain): python3 scripts/dash.py <url> for a live view, --once / --json for a scriptable snapshot — prefill/decode tok/s (computed-vs-admitted prefill, windowed headline + instant now + peak, per-request stream speed), engine steps/s and tokens/step, preemptions, queue depth, KV pressure against the lane's KV capacity, TTFT p50/p90, request lifecycle phases, mean prompt/output length, spec-decode acceptance rate/length and per-step wall time. Summed across the engine label (data-parallel lanes report the whole lane); keys q/p/r/w in the live view. --bench runs an active benchmark (warmup + 4 serial cases + a concurrency wave, each trial isolated by request counters — a busy lane or other traffic fails loudly; --out report.json never overwrites); --save-baseline blesses bench results or current rates as the lane's baseline, shown as base N.NN× ratios on later runs (store: ~/.cache/weightless/dash/baselines.json, keyed by model|ctx|version). Also in the wizard menu ("Watch a lane")
scripts/lane_watchdog.pycontainer-level self-healing for the rig: cron probe of the current lane's /v1/models every 5 min; three dead checks relaunch the lane via its start script (never docker start — RoCE GIDs re-resolve at launch). Boot-grace and switch-lock suppression; --install arms cron + the @reboot hook (scripts/lane-autostart.sh). A successful serve re-arms it on the head
tests/smoke/endpoint smoke tests: endpoint / chat / tool-call / headless omp agent loop — tests/smoke/README.md
docs/spec/GLP.mdthe GLP format spec: the glp.mode contract, layer-id mapping, why an additive reader must refuse the file
CHANGELOG.mddate-based ship log (no versioned releases yet); steering numbers live in BENCHMARK.md
BENCHMARK.mdsteering effectiveness (all GLP vectors, all suites, with domain coverage) + the serving run log

Real .env files are gitignored — only *.example templates are tracked.

Steering (live stack)

Off unless WEIGHTLESS_STEER_PATH is set. The env vars pass through recipe/anemll/docker-compose.dsv4.yml and the GGUF reader is embedded in the hotfix — nothing to build:

# the general/broad direction; the cyber-derived alternative
# (...-abliterated-cyber-GLP-29-L10-38-a4.gguf) is a one-line swap
WEIGHTLESS_STEER_PATH=/cache/huggingface/DeepSeek-V4-Flash-0731-general-abliterated-cvec-L10-38-a4-keysdir.gguf
WEIGHTLESS_STEER_ALPHA=4.0
WEIGHTLESS_STEER_LAYERS=$(seq -s, 10 38)

Confirm from the boot log — check that layers= reads 29, not 1:

weightless GLP steering active: hook=ffn_out_pre_residual alpha=4.000 ... layers=29 [10, ...]

A previous revision dedented the per-layer assignment out of its loop and steered one layer while reporting 29; coverage dominates this intervention (6 layers leaves 18.0% refusal, 29 leaves 0.0%). The structural tests in scripts/ guard that regression.

alpha is not a strength dial. At 1 the component is removed; past 1 it is reflected, which installs the behaviour rather than removing it. To run weaker, subset the layers and leave alpha alone. The 4.0 above is calibrated for this checkpoint; do not carry it to another model.

Steering on SGLang

The same GLP files and variables work on SGLang through sglang-plugin/; install it next to vllm-plugin/ (which provides the loader) in the SGLang environment:

pip install ./vllm-plugin ./sglang-plugin
WEIGHTLESS_STEER_PATH=<vector.gguf> python -m sglang.launch_server --model-path <model>

Each rank logs weightless GLP steering active (sglang): ...; no line means SGLang serves stock. Details: sglang-plugin/README.md.

Steering artifacts (ours)

Naming convention: GLP-n is a GLP vector touching n layers — GLP-29 below is the DSV4 vector, GLP-49 the Qwen one, GLP-47 the Flash-Next one, GLP-44 the GLM-Flash one, GLP-77 the GLM 743B one. All five lanes' vectors are published under msuiche/ on Hugging Face (gated — fetch with an HF token), spec-conformant per docs/spec/GLP.md and verified against their pinned checkpoint revisions.

  • msuiche/DeepSeek-V4-Flash-0731-abliterated-cyber-GLP-29 — DSV4 lane, GLP-29 (GGUF). Cyber-contrast vector: 29 per-layer directions over L10–38, n_embd 4096, α=4.0. The live config currently serves the general-contrast variant from the same repo family — a third-party direction we reformatted, re-measured and repackaged (attribution in the file metadata); swapping is one WEIGHTLESS_STEER_PATH line. Wiring: recipe/anemll/README.md.
  • msuiche/Qwen3.8-27B-abliterated-cyber-GLP-49 — Qwen lane, GLP-49 (GGUF + LoRA). The GGUF is canonical: per-layer diff of means, 49 directions over L10–58, n_embd 5120, α=1.0 (α=4 measurably over-refuses on this model). The rank-1 LoRA (mlp.down_proj, L1–63, α=1.0 baked) is the same intervention folded into weights — it loads in stock vLLM/peft/llama.cpp with no hotfix, matches the GGUF on NVFP4 hardware (both 24/32 refusal32, 2026-08-22), but is still unscored on the cyber holdout and is valid only for checkpoint revision 1d4bf0f2ff60 (lora_A embeds W). Wiring: recipe/qwen/README.md.
  • msuiche/Qwen3.8-Flash-Next-abliterated-cyber-GLP-47 — Qwen3.8-Flash-Next (qwen4_exp), GLP-47, day-0. Per-layer difference-of-means over the widened hyper-connection stream (10240 = 4×2560), layers 1–47, α=1.0. Derived 2026-08-26 on Modal (8×H100, BF16 reference) from AdvBench-vs-Alpaca. refusal32 3.1% → 81.2% at α=1.0 with benign32 32/32 and capability12 12/12 (higher α over-projects — do not raise it; the shipped default is the measured peak). Direction verified engine-independent: a vLLM-lane capture reproduces it at cos 0.9931. Serving lane: recipe/qwen38fn/ (TP=2 on 2x Spark, day-0 image; the hotfix steers the materialized hyper-connection stream).
  • msuiche/GLM-5.3-Flash-abliterated-cyber-GLP-44 — GLM-5.3-Flash (glm5_next), GLP-44, day-0. Per-layer dom over the Sinkhorn hyper-connection stream (16384 = 4×4096), layers 1–44, α=2.0. Derived from the FP8-native canonical checkpoint (snapshot 3f1971b7). refusal32 3.1% → 65.6% at α=2.0, benign/capability clean; α=2.5+ garbles everything — the cliff is abrupt, stay at or below 2.0. Serving lane: recipe/glm53/ (TP=4 on 4x Spark, NVFP4 quant on the sm121-v8 patched day-0 image; the hotfix steers the materialized mHC stream).
  • msuiche/GLM-5.3-abliterated-cyber-GLP-77 — GLM-5.3 743B (glm_moe_dsa), GLP-77. Per-layer dom over the plain residual stream (6144 — no hyperconnection widening on this arch), layers 1–77, α=1.0. Derived 2026-08-30 on the NVFP4 deployment (8×H100, vLLM 0.28.0) with the vLLM capture lane; every shipped layer clears the null gate. cyber32 18/32 → 32/32 at α=1.0 with benign/capability clean and a passing null arm; refusal32 moves 1/32 → 12/32 (37.5%; 6/32 answer-audited) — the 753B flagship's refusal is much stickier than Flash's, and α>1 makes it WORSE at full length (do not raise it). Serving lane: recipe/glm53xl/ (TP=4 on 4x Spark, tonyd2wild's Int4-Int8Mix stack; the hotfix steers hidden_states + residual on the deepseek_v2 path).
  • msuiche/gemma-3-1b-it-abliterated-GLP-20-L4-25-a0.25 — Gemma-3 1B (gemma3_text), GLP-20. Per-layer dom over the post-layer residual stream (1152), layers 4, 5, 8–25 zero-based — the null gate dropped 6 and 7, so the span genuinely carries gaps — α=0.25. First Google-family vector. Derived 2026-10-11 on Modal (A10G, transformers capture lane) from the byte-identical unsloth/gemma-3-1b-it mirror — the google/ repo is license-gated for our token, so the mirror revision is the pin in glp.base_revision. Stock already complies 29/32 on refusal32; the vector closes the last 3 with benign-holdout 32/32 at every rung, a byte-exact α=0 no-op and zero garbles. No serving lane — apply with glp.py or tools/captain-vector/apply_transformers.py.
  • msuiche/gemma-3-4b-it-abliterated-GLP-28-L6-33-a0.25 — Gemma-3 4B (gemma3 multimodal), GLP-28. Same recipe over the post-layer residual stream (2560), layers 6–33 zero-based (contiguous), α=0.25. First multimodal-arch derivation: the checkpoint is Gemma3ForConditionalGeneration and the steered text stack resolves at model.language_model.layers. Stock refusal32 30/32 → 32/32 at α=0.25, benign-holdout 32/32 every arm, α=0 no-op byte-exact, zero garbles. Same unsloth-mirror base pin; apply with glp.py / apply_transformers.py.
  • msuiche/gemma-3-12b-it-abliterated-GLP-43-L5-47-a0.25 — Gemma-3 12B (gemma3 multimodal), GLP-43. Post-layer residual stream (3840), layers 5–47 zero-based (contiguous), α=0.25. Stock refusal32 30/32 → 32/32 at α=0.25, benign-holdout 32/32 every arm, α=0 no-op byte-exact, zero garbles. Same unsloth-mirror base pin; apply with glp.py / apply_transformers.py.
  • msuiche/gemma-3-27b-it-abliterated-GLP-51-L11-61-a0.25 — Gemma-3 27B (gemma3 multimodal), GLP-51. Post-layer residual stream (5376), layers 11–61 zero-based (contiguous), α=0.25. Stock refusal32 29/32 → 31/32 at the shipped α=0.25 (32/32 from α=0.5 up — the knee rule ships the bottom rung), benign-holdout 32/32 every arm, α=0 no-op byte-exact, zero garbles. Same unsloth-mirror base pin; apply with glp.py / apply_transformers.py.
  • msuiche/gemma-4-E2B-it-abliterated-GLP-31-L4-34-a0.5 — Gemma-4 E2B (gemma4 multimodal), GLP-31. Post-layer residual stream (1536), layers 4–34 zero-based (contiguous), α=0.5. Derived 2026-10-11 on Modal (A10G, transformers 5.19.0 capture lane) from canonical google/gemma-4-E2B-it — unlike gemma-3, the gemma-4 google/ repos serve weights to our token, so no mirror; the google/ revision sha is the pin in glp.base_revision. Stock refuses hard — 4/32 comply on refusal32 — and the ladder is monotone (28 → 31 → 32), so the vector does real unlocking: 31/32 at the shipped α=0.5 with benign-holdout 32/32 at every rung, a byte-exact α=0 no-op and zero garbles. No serving lane — apply with glp.py or tools/captain-vector/apply_transformers.py.
  • msuiche/gemma-4-E4B-it-abliterated-GLP-33-L5-41-a1 — Gemma-4 E4B (gemma4 multimodal), GLP-33. Post-layer residual stream (2560), layers 5, 10–41 zero-based — the null gate dropped 6–9, so the span genuinely carries a gap — α=1.0. The family's hardest refuser: stock refuses 31/32 on refusal32 (the lone "comply" is a scorer artifact) and the ladder is the steepest (15 → 25 → 32), so the knee rule climbs past 0.5 and ships full α — 32/32 steered with benign-holdout 32/32 at every rung, α=0 no-op byte-exact, zero garbles. Same canonical google/ base pin; apply with glp.py / apply_transformers.py.
  • msuiche/gemma-4-12B-it-abliterated-GLP-33-L15-47-a0.5 — Gemma-4 12B (gemma4_unified), GLP-33. Post-layer residual stream (3840), layers 15–47 zero-based (contiguous), α=0.5. The unified arch: vision/audio embedders into the shared text stack, no towers (the four siblings are plain gemma4 with real towers + PLE; both nest the steered stack at model.language_model.layers). Stock already complies 32/32 on refusal32, so this ladder is the no-regression story — and it is non-monotone: α=0.25 dips to 29/32, α=0.5 and 1.0 hold 32/32 with benign-holdout 32/32 every arm, α=0 no-op byte-exact, zero garbles. Same canonical google/ base pin; apply with glp.py / apply_transformers.py.
  • msuiche/gemma-4-26B-A4B-it-abliterated-GLP-27-L3-29-a0.5 — Gemma-4 26B-A4B (gemma4 multimodal, MoE), GLP-27. Post-layer residual stream (2816), layers 3–29 zero-based (contiguous), α=0.5. The first MoE derivation in the gemma line: 128 experts top-8 summed with a dense MLP per hybrid layer (~26B total / ~4B active) — the hook sits on the decoder-layer output downstream of router+experts, and direction quality matches the dense 12B (span min cos 0.575 vs 0.559). Stock complies 32/32; the ladder dips to 25/32 at α=0.25 and recovers to 31/32 at the shipped α=0.5 (α=1.0 flips two benign-holdout prompts and fails that gate), benign-holdout 32/32 at the shipped rung, α=0 no-op byte-exact, zero garbles. Same canonical google/ base pin; apply with glp.py / apply_transformers.py.
  • msuiche/gemma-4-31B-it-abliterated-GLP-54-L6-59-a0.5 — Gemma-4 31B (gemma4 multimodal), GLP-54. Post-layer residual stream (5376), layers 6–59 zero-based (contiguous), α=0.5. The dense flagship (60L, vision/audio towers + PLE). Stock complies 32/32 on refusal32; the shallowest non-monotone dip of the family — α=0.25 gives 30/32, α=0.5 holds 32/32, α=1.0 re-engages one refusal — benign-holdout 32/32 at every rung, α=0 no-op byte-exact, zero garbles. Same canonical google/ base pin; apply with glp.py / apply_transformers.py.

Roadmap

  • More model lanes. The GLP spec and the fail-closed hotfix pattern are model-agnostic — DSV4 and Qwen3.8 are the starting lanes, not the scope. The target is most good open models, one recipe/ lane and one published GLP vector each. Day-0 vectors for Qwen3.8-Flash-Next (GLP-47) and GLM-5.3-Flash (GLP-44) shipped 2026-08-27, GLM-5.3 743B (GLP-77) 2026-08-30; their serving lanes are recipe/qwen38fn/ (TP=2), recipe/glm53/ (TP=4, needs 4 nodes) and recipe/glm53xl/ (TP=4, 4 nodes + the Int4-Int8Mix stack).
  • k=7/greedy draft A/B (upstream issue #84): now one env line (DRAFT_SAMPLE_METHOD=greedy MTP_NUM_TOKENS=7) after the 2026-08-21 upstream merge.
  • Qwen LoRA cyber-holdout score (run L): both Qwen steering arms match on refusal32; the LoRA arm still needs its cyber-holdout number before it can replace GGUF as the default. Lives in the eval pipeline, not this repo.

References & credits

Fallback: the retired v027 stack

Parked, not deleted — the v0.27 git patch and its test remain under patches/. Essentials if you ever revive it:

  • Maintenance home is the dspark-steering-v027 branch of msuiche/vllm, so upstream bumps get a real 3-way merge. Regenerate with: git -C ../vllm diff v0.27.0..dspark-steering-v027 -- vllm/models/deepseek_v4/nvidia/model.py > patches/0001-dspark-projective-steering.patch
  • Apply without an image build: run the stock v027 image and bind-mount the patched model.py over the original. Resolve the in-image path first (it is /opt/vllm-src/vllm, a source install — bind-mounting a path that does not exist silently creates it and yields an inert patch; the layers=29 boot line is the confirmation steering is live).
  • Base image: ghcr.io/bjk110/vllm-spark:v027-ngc2607-dsv4-0731-dspark-k7-256k-production (registry is rate-limited for anonymous pulls — docker login ghcr.io first). It has no gguf module: build recipe/Dockerfile.gguf-dep and point DSPARK_VLLM_IMAGE at it. Never load a .pt instead — that goes through torch.load and bypasses every spec check in the reader.
  • Settled v027 config: context 1,032,192 (1,048,576 collapses prefill to 110 tok/s), KV fp8_ds_mla, spec decode dspark k=5, max-num-seqs 6. Measurements: BENCHMARK.md Runs 001–005.
inference

msuiche/weightless

Abliteration without the weights — projective refusal steering as a GLP vector + fail-closed boot hotfix.

Python

86

322 commits

updated Oct 18, 2026

See the code

See what people are saying

SourceMessageScoreDate

Uncensored models via LORA (r/LocalLLaMA)

I know the heretic tool is the usual generic approach to remove refusals from a model, and a lot of research has been done to find out what parts in the LLM need to change. This gets very expensive though the larger the model is. Then for Krea2 turbo/base I saw that there are LORAs to remove…

25

Oct 17, 2026

Abliteration Without the Weights

2

Aug 23, 2026

README

weightless feather logo

weightless

Abliteration without the weights — put your model on GLP. Projective refusal steering for open-weight models: serving config, boot hotfixes, the steering patch, and the GLP (GGUF Layer Projection) format spec. The goal is most good open models; the lanes are DeepSeek V4 Flash 0731 on 2x DGX Spark (GB10, SM121, TP=2 over RoCE), Qwen3.8-27B on a single Spark, Qwen3.8-Flash-Next NVFP4 on 2x DGX Spark (TP=2, day-0 image), and GLM-5.3-Flash NVFP4 on 4x DGX Spark (TP=4, patched day-0 image), and GLM-5.3 743B Int4-Int8Mix on 4x DGX Spark (TP=4, tonyd2wild's recipe). The method and the measurements behind it are in the original write-up: Abliteration without redistributing the model.

The live DSV4 stack is the Anemll image (ghcr.io/anemll/dspark-vllm-gx10:0.1.1, vLLM 0.25.2) driven by the MiaAI 2x recipe, with our state on top vendored in recipe/anemll/; the Qwen lane (stock vLLM 0.27 image, GGUF or LoRA steering) lives in recipe/qwen/; the Qwen3.8-Flash-Next lane (day-0 image vllm/vllm-openai:qwen38-flash-next, GLP-47) lives in recipe/qwen38fn/; the GLM-5.3-Flash lane (tonyd2wild's sm121-v8 patch stack on the day-0 vllm/vllm-openai:glm53-flash-arm64-cu130, GLP-44) lives in recipe/glm53/; the GLM-5.3 743B lane (tonyd2wild's Int4-Int8Mix stack, GLP-77) lives in recipe/glm53xl/. The retired v027 stack's patch is kept for reference and as the fallback path.

setup wizard — splash, local-state box, main menu

Quick start

python3 weightless.py          # the one front door — interactive setup wizard
python3 weightless.py serve 0  # switch the rig to a lane, no prompts (serve <name|#>)
python3 weightless.py dash     # live metrics for the serving lane
python3 weightless.py test     # endpoint smoke suite
python3 weightless.py --help   # all commands

weightless.py (Python 3.9+, stdlib only) dispatches to the real scripts, which also work standalone: setup.py (TUI wizard with a prompt fallback), scripts/dash.py, tests/smoke/run.sh.

Use python3 weightless.py help <command> for command-specific options. python3 weightless.py setup --plain uses text prompts; setup requires an interactive terminal. With redirected stdin, invoking weightless.py without arguments prints help. serve rejects unknown flags before deployment; omit its lane argument to list available lanes.

For scripts, python3 weightless.py dash <url> --once --timeout 5 prints a snapshot (two samples --interval apart, so its rates are real) and exits nonzero if the endpoint fails or returns no vLLM metrics; --json prints the same numbers as one JSON object. Dashboard URLs may include /v1 or /metrics. Refresh intervals, rate windows and request timeouts must be positive and finite. Redirected dashboard output contains no terminal control sequences; NO_COLOR disables colors in both prompts and the dashboard. In the live view q quits, p pauses, r resets the session counters and w cycles the rate window (10 / 30 / 60 / 300s).

Swapping lanes is the wizard, not ssh. Pick Serve <model> for the lane you want: the wizard regenerates the env, re-validates it (multi-node fabric addresses must be literal IPs — containers cannot resolve .local; the steering vector's glp.hook_point is read on the node and must match the lane's enforced site), parks the running lane's containers, drops page caches, boots, then reconfigures omp/hermes and runs the smoke suite. If a swap ever needs a manual ssh incantation, that gap goes into the wizard — not into shell history.

Pick a lane and it walks the full chain: site values → env file → steering validation → asset preparation → confirm-gated ssh deploy → omp provider (registered in omp's modelRoles — default role, or every text role) + endpoint smoke tests. Endpoint down? The diagnose chain isolates DNS → TCP → HTTP and can check and boot the stack over ssh. Non-interactive alternative: sh tests/smoke/install.sh && sh tests/smoke/run.sh with DSPARK_* env overrides.

Asset preparation downloads the model on the head, rsyncs its HF cache to workers over the fabric, pulls the recipe image on each node, and downloads the selected GLP file on every node. Each command is printed and confirmed; downloads resume on reruns. Set HF_TOKEN or use hf auth login locally after accepting access to the gated vector repository. The token travels over SSH stdin and is never printed. Remote HF tooling uses its own venv (nodes need Python 3 with venv support). GLM 743B still requires the recipe's local image build, kernel overlay and mounted weight directories; the wizard verifies that image instead of attempting to pull a nonexistent registry tag. Before boot, switching lanes offers a separate, default-no confirmation to remove the old lane's containers on its nodes and prints the relaunch command. DEMO=1 python3 setup.py skips writes, downloads and all network commands.

What this is: lean abliteration steering as a patch

The model weights are never redistributed — what this repo ships is the intervention, tested and self-contained:

  • The steering file. A GLP vector — a spec-conformant control-vector GGUF (docs/spec/GLP.md) with per-layer directions, derived by us and published under msuiche/ (see Steering artifacts). No model weights inside.
  • The patch. The installable plugin (vllm-plugin/, dist weightless-steer): one adapter per architecture in weightless_steer/archs/ shadows the model class in vLLM's ModelRegistry, installing the same projective hook with no container file rewrites at all — ten archs, every one GPU-validated on Modal (2026-09-18/19, per-lane numbers in BENCHMARK.md). The boot hotfixes (patches/hotfix-*.py) are the per-lane mechanism the plugin replaces: still what the live rigs run today, kept as the fallback stack and as the semantic reference each adapter is pinned against by structure tests (tests/structure/, vllm-plugin/tests/).
  • Quant-friendly. The hook steers activations at runtime (the calibrated site per lane: post-layer residual where the runtime materialises it, the pre-fold FFN write on the DSV4 lane, 2026-09-04 site correction), so it works on quantized checkpoints (NVFP4 verified on both lanes, bf16→NVFP4 transfer measured) as long as the base architecture is intact. The one exception is REAP-pruned builds: deleting experts changes the shape of the base model, the vector no longer matches the circuit, and the lane is rejected on those grounds (see Lanes).
  • A no-patch option for Qwen. The same intervention folded into a rank-1 LoRA we reproduced — it loads in stock vLLM/peft with no hotfix at all and matches the GGUF arm on hardware (both 24/32 refusal32).

Internals write-up: Abliteration without redistributing the model.

Streams and writers — and why GLP is not a LoRA

Two objects get confused often enough that GLP ends up misfiled as a LoRA variant. They are different objects, and the difference is the whole design:

  • The residual stream is the running sum a token carries through the network: the embedding output plus everything every layer has added so far. It is an activation — it exists only at runtime, and no single weight matrix sits behind it. A behavioral direction "in the residual stream" means a direction in that accumulated quantity.
  • A residual writer is one of the matmuls whose output gets added into the stream: self_attn.o_proj, mlp.down_proj (linear_attn.out_proj on hybrid archs). Each writer has a concrete W you can read and edit.

GLP's native object is a direction d̂ in the stream, and its native operation projects the accumulated stream at runtime: h ← h − α(h·d̂)d̂, applied by a hook after each listed layer. Activation space, α tunable at serve time, architecture-blind, nothing re-baked.

A LoRA can only express a weight delta ΔW = B·A on an existing matmul. "Project the stream" has no single W behind it, so it cannot be written as a LoRA. What can be written is "project each residual writer": at h = Wx the projection is exactly ΔW = −α·d̂(d̂ᵀW) — the Arditi et al. weight-orthogonalization form, which is what captain-vector bake emits as a rank-1 adapter. Every limitation of the baked form follows from that one substitution:

  • Writer ≠ stream. Projecting all of a layer's writers at α equals projecting that layer's new contributions at α (linearity) — but a d̂-component already riding the incoming stream (embeddings, an unbaked writer) passes through, where the runtime hook removes it regardless of origin. Close in practice, not bit-identical.
  • Dense-only in practice. On MoE the writers are per-expert — hundreds of matrices per layer — so a bake explodes into thousands of rank-1s against quantized weights. Runtime stream steering is architecture-blind; the MoE lanes here (DSV4, GLM, Hy4, K3) exist because of it.
  • α is frozen into lora_A — not tunable at serve time, and scaling the adapter double-doses.
  • Checkpoint-bound. lora_A carries W; baked against the wrong base revision the adapter is garbage and nothing downstream flags it (bake's pin check fails closed for exactly this reason).

The same constraint runs the other way: llama.cpp control vectors and the steering-LoRAs that circulated before GLP are addition-only (h ← h + scale·d), and addition cannot express "remove the d̂-component of whatever passes through here" — nor bake exactly anywhere (a constant shift is a bias, not a weight delta). Add-vs-project and runtime-vs-baked are two independent axes. GLP occupies the projective, runtime-native quadrant; the baked adapter is its portable shadow for stacks that only speak LoRA.

Deeper: FAQ.md (answers to the questions people actually ask — backdoor auditability, vector maintenance under retraining, effective range, MoE/loop coverage, dosage, termination), docs/spec/GLP.md (the format contract), docs/llama-cpp-compat.md (source-verified mechanics), tools/captain-vector/README.md (bake's troubleshooting/interop role).

The stack

Serving is vLLM (the only runtime with working sm_121a NVFP4 + MTP paths for these checkpoints on GB10), driven by omp as the agent harness/client — we picked it over stock Pi for the benchmaxxed tool loop (hash-anchored edits, LSP/DAP wired in, fast headless mode), and this repo's tests/ suite proves the served model can drive it end to end. Steering is optional per lane and off by default when the steer path is empty:

flowchart LR
    subgraph client[client]
        OMP["omp<br/>agent harness"]
        WIZ["setup.py<br/>wizard + tests/"]
    end
    OMP -->|OpenAI-compatible /v1| EP["vLLM endpoint<br/>:8888, :8078, :8079, :8080 or :8081"]
    WIZ -->|probe / diagnose / boot| EP
    EP --> DSV4["DSV4 lane — TP=2<br/>2x DGX Spark over RoCE<br/>DeepSeek-V4-Flash-0731 NVFP4"]
    EP --> QWEN["Qwen lane — TP=1<br/>single DGX Spark<br/>Qwen3.8-27B NVFP4"]
    EP --> QWENFN["Flash-Next lane — TP=2<br/>2x DGX Spark over RoCE<br/>Qwen3.8-Flash-Next NVFP4"]
    EP --> GLM["GLM-5.3-Flash lane — TP=4<br/>4x DGX Spark over RoCE<br/>GLM-5.3-Flash NVFP4"]
    CV["GLP vector (GGUF)<br/>fail-closed boot hotfix"] -.->|optional| DSV4
    CV2["GLP vector hotfix<br/>or rank-1 LoRA, no patch"] -.->|optional| QWEN
    CV3["GLP-47 vector (GGUF)<br/>fail-closed boot hotfix"] -.->|optional| QWENFN
    CV4["GLP-44 vector (GGUF)<br/>fail-closed boot hotfix"] -.->|optional| GLM
    EP --> GLMXL["GLM-5.3 743B lane — TP=4<br/>4x DGX Spark over RoCE<br/>GLM-5.3 Int4-Int8Mix"]
    CV5["GLP-77 vector (GGUF)<br/>staged fail-closed hotfix"] -.->|optional| GLMXL

The lanes never run at once: each multi-node lane (DSV4 on 2, Flash-Next on 2, the GLM lanes on 4) already holds its Sparks' GPUs, and the Qwen lane is parked until the multi-node stack is down.

endpoint smoke tests running inside the wizard

Lanes

lanehardwaremodelsteeringstatus
DSV4 TP=2both Sparks over dual-rail RoCEDeepSeek-V4-Flash-0731, NVFP4 (166.9 GB)projective cvec, live on 29 layerslive — recipe/anemll/
DSV4-Vision-Exp TP=2both Sparks over dual-rail RoCEDeepSeek-V4-Flash-Vision-Exp, FP8 original (202 GB)projective cvec, L10–38 at α=1.0 (the -ffn hook relabel of GLP-29 Vision-Exp)live (text-only) — the 0.25.2 image's loader refuses the checkpoint's vision.*/aligner tensors, so this lane serves the vision-stripped FP8 tree (strip_vision.py output, staged at $HF_CACHE/visionexp-text-fp8); recipe/anemll/ (.env.dsv4vx + start-deepseek-v4-flash-visionexp-dspark.sh). Vision-capable serving is the VL lane below
DSV4-Vision-Exp VL TP=2both Sparks over dual-rail RoCEDeepSeek-V4-Flash-Vision-Exp, FP8 unstripped (snapshot 6821d6ad, vision enabled)same -ffn GLP-29 relabel, L10–38 at α=1.0 (day-0 tree keeps the deferred mHC fold → ffn_out_pre_residual)first-boot-validated 2026-09-23 (2x DGX Spark, GB10) — recipe/dsv4vl/; day-0 vLLM (0.28.1rc1 + PR #54566) on vllm-upstream-vision:k2-topk512 (flashinfer 0.6.18 + DSV4 dual-prefill topk 192/256/512 backport, msuiche/flashinfer); nospec; cold boot 8m24s; steering A/B green (α=0.0 base-like, α=1.0 cyber 4/4 comply, benign 4/4 both arms, ~13.4 tok/s single-stream both arms); vision smoke under steering green (image-token math 315∈[314,317], 111∈[110,113], mix, text-only, concurrency)
Qwen TP=1one SparkQwen3.8-27B-NVFP4 (~13.5 GB)per-layer cvec, L10–58 at α=1.0 (shipping artifact)hardware-validated — recipe/qwen/; stock 4/32, GGUF 24/32, LoRA 24/32 on refusal32 (2026-08-22)
Qwen3.8-Flash-Next TP=2both Sparks over RoCEQwen3.8-Flash-Next-NVFP4 (~135 GB), day-0 imageper-layer cvec, L1–47 at α=1.0 (GLP-47)hardware-validated 2026-09-01 (2x DGX Spark, GB10) — recipe/qwen38fn/; steered live on the pair: refusal32 22/32 (stock 1/32), KV pool 35.3 GiB @ 262K native ctx; earlier cloud validation (2xB200): refusal32 1/32 → 26/32, benign 32/32; vector eval 81.2% refusal32 (vLLM lane, cos 0.9931 vs HF)
DSV4-Vision-Exp (Modal lane)4×H100 (tolmo)DeepSeek-V4-Flash-Vision-Exp, FP8 (~168 GB)per-layer cvec, L10–38 at α=1.0 (GLP-29 Vision-Exp)vector-validated 2026-09-01 — refusal32 1/32 → 27/32 fresh (α=4 garbles — dose cliff), benign32 32/32 both arms; the 0731 GLP-29 keysdir vector transfers at 31/32 despite cos −0.32 (multi-directional refusal); Spark lane: the TP=2 row above
DSV4-Vision-Exp NVFP42×B200 (tolmo)msuiche/DeepSeek-V4-Flash-Vision-Exp-NVFP4 (176.5 GB, modelopt W4A4, experts-only)same GLP-29 vectorsboot-validated 2026-09-03 (stock vLLM 0.28.0, first vLLM boot of vision-exp) — lossless MXFP4→NVFP4 transcode (byte-exact vs NVIDIA's recipe); NVFP4 ≈ FP8 ±1 item on refusal32, benign 32/32, capability 12/12, zero garbles; steered-delivery delta vs the old HF-lane numbers is a lane effect (fp8 KV + kernels), not the quant — FP8 control lands the same; strip_vision.py in-repo for stock-vLLM text boot; GB10 via modelopt_gb10_hybrid plugin
Inkling-Small TP=2both Sparks over RoCEInkling-Small-NVFP4 (159 GiB), stock vLLM 0.28.0, CUDA graphs onper-layer cvec, L1–41 at α=0.25 (GLP-41)hardware-validated 2026-09-04 (2x DGX Spark, GB10) — recipe/inkling/; real weights boot and serve with the load-reclaim + sm121 rel-attention hotfixes (78.3 GiB model, 21.4 GiB KV, 4/4 smoke); Modal lane: refusal32 0/32 stock (total lockdown) → 30/32 steered, benign32 30/32; α=1.0 garbles everything — the most dose-sensitive model in the program; first GLP for a Thinking Machines model
Hy4-preview (Modal lane)8×H200 (tolmo)tencent/Hy4-preview-FP8 (770B / 49B active, ~770 GB), day-0 imageper-layer cvec, L1–77 at α=2.0 (GLP-77 Hy4)vector-validated 2026-09-02 — refusal32 1/32 → 24/32, cyber32 15/32 → 31/32, benign32 32/32 at α=2.0 (collateral non-monotonic: worst at α=1.0–1.5, zero at full dose); no garble at any dose — most steer-tolerant arch in the program; largest model with a published refusal vector; caveat: refusal32 answers all run to the 4K cap at α=2.0
GLM-5.3-Flash TP=4four Sparks over RoCEGLM-5.3-Flash-NVFP4 (~50 GiB/rank), othexmr's RiNGSiDE recipe (switchless ring NCCL + b12x kernels; previously the sm121-v8 patched day-0 image)per-layer cvec, L1–44 at α=2.0 (GLP-44)live in production since 2026-09-29 — recipe/glm53/; 1M context, 36 tok/s freeform → 53–64 tok/s structured/agentic with DFlash2 spec decode (acceptance is regime-dependent; steering costs none — measured, see below); vector eval 65.6% refusal32 at α=2.0; α≥2.5 garbles this model
GLM-5.3 743B TP=4four Sparks over RoCEGLM-5.3 Int4-Int8Mix (~95.5 GiB/rank), tonyd2wild's stack (local image + sm12x overlay)per-layer cvec, L1–77 at α=1.0 (GLP-77)hotfix live-validated 2026-08-30 — recipe/glm53xl/; on stock vLLM 0.28.0 (8×H100, RadixArk/GLM-5.3-NVFP4): refusal32 1→10/32, cyber32 15→31/32; the 4x-Spark GB10 lane itself remains untested (needs the hardware); vector eval (8×H100, full-length): cyber32 32/32, refusal32 12/32 (37.5%; 6/32 answer-audited) at α=1.0, null arm = stock; refusal on the 753B is much stickier than Flash — α>1 makes it WORSE
GLM-5.3 743B cloud (Modal lane)8×H100, wizard-deployedRadixArk/GLM-5.3-NVFP4 (~465 GB), stock vLLM 0.28.0same GLP-77, α=1.0deployable — modal/cloud_serve.py; delivers an OpenAI-compatible endpoint, no rig needed
Kimi K3 2.9T cloud (Modal lane)2×H200:8 (PP=2 x TP=8, TCP fabric), wizard-deployedmoonshotai/Kimi-K3 (~1.56 TB, MXFP4 experts), day-0 imageper-layer cvec, L1–92 at α=1.0 (GLP-92)vector-validated 2026-09-04 — refusal32 1/32 → 31/32, cyber32 17/32 → 32/32, zero collateral (benign32 32/32, propaganda32 32/32); modal/cloud_serve_k3.py: collective lockstep serving (the fork's multi-node serve shape wedges), deploys to an OpenAI-compatible endpoint

GLM-5.3-Flash needs 4 nodes — and a patched image. At TP4 the NVFP4 quant is ~50 GiB of weights per 128 GB node, which is what makes the 1M-context KV pool possible. Since 2026-09-29 the production lane runs othexmr's RiNGSiDE (switchless ring NCCL, b12x kernels, RDMA prefill, DFlash2 drafting; TP2 and TP4 profiles) with the GLP-44 steering mounted via its weightless launcher option. A 2-node TP2 config exists (262K context, KV-starved — tonyd2wild's TP2 repo) but stays out of scope for this wizard lane. The stock day-0 vendor image dies five different ways on GB10; the lane requires the sm121-v8 patch stack (radixark/vllm-glm53-flash:sm121-v8 or a local v1→v8 build — details in recipe/glm53/README.md). If your machines.txt lists two nodes, this lane cannot boot until two more are racked and cabled. The 743B lane needs the same four nodes plus tonyd2wild's Int4-Int8Mix weights (377.4 GiB) and stack (image + kernel overlay — recipe/glm53xl/README.md); its first real boot is the anchor test (the hotfix stages fail-closed before GPU time). On x86 SM120 instead of Sparks, brandonmusic's EXL3/B12X build (brandonmusic/GLM-5.3-Flash-tr3-4bpw, custom vLLM fork) takes the same GLP-44 hotfix mechanics — see recipe/glm53/README.md (runtime-validated on 2x RTX PRO 6000: refusal32 1→15/32, cyber32 14→31/32).

DFlash2 spec decode and steering — measured, not assumed (2026-08-30, 4xH100, Prometheus spec_decode counters): GLP-44 steering at α=2.0 costs the drafter no acceptance — structured 81.4% → 87.1% steered, prose 26.1% → 24.4% — because the drafter's aux-capture taps sit before the steering injection point and condition on pre-steering features. The stock tap set [5,14,24,33,42] ships in the drafter's own config.json and is training-matched: a 7-set sweep found every alternative worse, tapping the final target layer poisons the drafter (~6% acceptance), and the tap count is fixed by the checkpoint's fc width. Prose acceptance (~26% Flash, ~23% flagship) is a drafter-capacity limit, not a tap-tuning opportunity — do not retune the taps.

Single-Spark DSV4 (EXL3 3.0bpw + REAP-K216): evaluated and rejected. The full NVFP4 checkpoint (166.9 GB) cannot fit one Spark, so single-node DSV4 exists only as the pruned/quantized artifact — REAP deletes 40 of 256 routed experts per MoE layer on top of the 3.0bpw quant. Benchmarks pass, but the degradation concentrates in rare behaviour by construction, and the control vector would need re-deriving on the pruned circuit. TP=1 DSV4 is a smaller, approximated model; we do not serve it. The steering contract in docs/spec/GLP.md remains lane-independent.

Layout

pathwhat it is
weightless.pysingle front-door CLI: weightless.py (wizard), weightless.py dash, weightless.py test, `weightless.py validate
setup.pyfull-chain setup wizard (TUI or prompts, stdlib-only): lane pick → env file → steering validation → ssh deploy → omp provider + tests, plus a diagnose chain (DNS → TCP → HTTP → remote docker/GPU status, optional boot)
recipe/anemll/live: compose / start script / .env.dsv4.example for the MiaAI 2x clone, plus rebuild notes
recipe/qwen/Qwen TP=1 lane: serve script + .env.qwen.example; STEER_MODE=gguf|lora, both hardware-validated
recipe/qwen38fn/Qwen3.8-Flash-Next TP=2 lane: head+worker start script + .env.qwen38fn.example; --no-enable-prefix-caching and VLLM_PLE_CPU_OFFLOAD=1 are mandatory there
recipe/glm53/GLM-5.3-Flash TP=4 lane: head+3-worker start script + .env.glm53.example; needs 4 nodes and the sm121-v8 patched image, α=2.0 is calibrated (α≥2.5 garbles)
recipe/glm53xl/GLM-5.3 743B TP=4 lane: head+3-worker start script + .env.glm53xl.example; needs 4 nodes + tonyd2wild's Int4-Int8Mix weights/stack, α=1.0 is calibrated (higher makes refusal worse)
patches/hotfix-dsv4-steering-projective.pylive: steering as a fail-closed boot hotfix for the 0.25.2 image (embedded GGUF reader)
patches/hotfix-qwen38-steering-projective.pythe same steering for the Qwen lane: patches qwen3_next.py + qwen3_5.py, steers hidden_states + residual
patches/hotfix-qwen38fn-steering-projective.pythe same steering for the Flash-Next lane: patches the day-0 image's vllm/models/qwen3_8_flash_next/nvidia/model.py, steers the materialized hyper-connection stream (10240 = 4×2560)
patches/hotfix-glm53-steering-projective.pythe same steering for the GLM-5.3 lane: patches vllm/models/glm5next/nvidia/model.py, steers the materialized mHC stream (16384 = 4×4096); the last layer's in-decoder contract is deferred so L44 is covered
patches/hotfix-glm53xl-steering-projective.pythe same steering for the GLM-5.3 743B lane: patches the overlay's deepseek_v2.py copy at staging (the mount is read-only), steers hidden_states + residual (decomposed convention, no HC widening)
patches/hotfix-glm53-exl3-steering-projective.pythe GLM-5.3-Flash steering for brandonmusic's EXL3/B12X fork image (SM120): the fork's DFlash branch splits the decoder loop in two — the variant patches both (aux loop steers after the aux capture, pre-steer features)
vllm-plugin/the same steering as an installable vLLM plugin (dist weightless-steer, vllm.general_plugins entry point): one adapter per architecture in weightless_steer/archs/ shadows the model class in ModelRegistry instead of rewriting files in the container — the successor to the hotfix fleet above. Ten adapters today: nemotron_h.py, glm5next.py, dsv4.py, qwen38.py, qwen38fn.py, glm53xl.py, kimi_k3.py, ouro.py, inkling.py, hy4.py. glm5next GPU-validated 2026-09-18 (Modal 4×H100, GLM-5.3-Flash NVFP4, compiled mode — cyber32 31/32 exactly the hotfix reference, benign32 clean, refusal32 2→9/32 vs 1→21/32 hotfix on a stiffer stock baseline; modal/cloud_serve_glm53.py); the other eight new adapters GPU-validated 2026-09-19 on Modal (verification depth varies — full eval for dsv4/qwen38/qwen38fn/ouro/inkling, boot+smoke for hy4/glm53xl/kimi-k3; per-arch numbers in BENCHMARK.md, raw artifacts in modal/out-<arch>-plugin-test/). Design: docs/vllm-plugin-design.md, offline tests need neither GPU nor vLLM
sglang-plugin/the same steering as an installable SGLang plugin (dist weightless-sglang, sglang.srt.plugins entry point): an AFTER hook on ModelRunner.load_model installs the steering sites before CUDA-graph capture, with no SGLang source change, and reuses the vLLM plugin's loader and gates. One module per architecture in weightless_sglang/archs/: Qwen3.8-27B (one RTX 5090) and GLM-5.3-Flash (3x RTX PRO 6000, PP 3) GPU-validated 2026-09-25/26, seven more structure-tested on CPU. The edit runs as one fused Triton kernel by default, self-checked at start-up against a torch path that gives the same bits. Design: docs/sglang-plugin-design.md; offline tests need neither GPU nor SGLang
patches/vendor/sparse_attn_indexer_kpool_sm121.pyvendored SM121 indexer top-k fix (tonyd2wild's DFlash2 repo, provenance header inside): bind-mounted over the in-image file on every glm53 node — without it both published images hard-kill on decode past ~24K context
patches/reference/glm5next_b12x_exl3.pythe EXL3 structure test's reference — the model file extracted from the published verdictai/glm53-flash-exl3-k4 image (OCI layer sha256:7f03081e…)
patches/reference/deepseek_v2_glm53xl.pythe 743B structure test's reference — tonyd2wild's kernel-overlay deepseek_v2.py (the file his stack actually serves); same anchors as vLLM v0.28.0
patches/reference/qwen3_8_flash_next.pybyte-identical copy of the day-0 image's model file — the Flash-Next structure test's reference (the ../vllm checkout predates the arch)
patches/reference/glm5next.pythe GLM-5.3 structure test's reference — from the day-0 PR source (vllm-project/vllm#53906); re-vendor against the image on first deploy
patches/0001-*.patch, 0002-*.patchthe hook + its vLLM-side test as git patches against v0.27.0 (fallback stack)
recipe/ (top level)retired v027 stack: Dockerfiles + compose
tests/structure/structural guard tests for the steering patches (test-*-structure.py, incl. test-steering-structure.py for the retired v027 overlay)
scripts/dash.py (below), dspark-router.py, memory-watchdog-gpu.sh, probe-refusal.py
scripts/dash.pylive terminal view of any serving lane (stdlib only, ANSI colors on a terminal — brand pink/cyan, KV gauge green→yellow→red; --no-color/NO_COLOR for plain): python3 scripts/dash.py <url> for a live view, --once / --json for a scriptable snapshot — prefill/decode tok/s (computed-vs-admitted prefill, windowed headline + instant now + peak, per-request stream speed), engine steps/s and tokens/step, preemptions, queue depth, KV pressure against the lane's KV capacity, TTFT p50/p90, request lifecycle phases, mean prompt/output length, spec-decode acceptance rate/length and per-step wall time. Summed across the engine label (data-parallel lanes report the whole lane); keys q/p/r/w in the live view. --bench runs an active benchmark (warmup + 4 serial cases + a concurrency wave, each trial isolated by request counters — a busy lane or other traffic fails loudly; --out report.json never overwrites); --save-baseline blesses bench results or current rates as the lane's baseline, shown as base N.NN× ratios on later runs (store: ~/.cache/weightless/dash/baselines.json, keyed by model|ctx|version). Also in the wizard menu ("Watch a lane")
scripts/lane_watchdog.pycontainer-level self-healing for the rig: cron probe of the current lane's /v1/models every 5 min; three dead checks relaunch the lane via its start script (never docker start — RoCE GIDs re-resolve at launch). Boot-grace and switch-lock suppression; --install arms cron + the @reboot hook (scripts/lane-autostart.sh). A successful serve re-arms it on the head
tests/smoke/endpoint smoke tests: endpoint / chat / tool-call / headless omp agent loop — tests/smoke/README.md
docs/spec/GLP.mdthe GLP format spec: the glp.mode contract, layer-id mapping, why an additive reader must refuse the file
CHANGELOG.mddate-based ship log (no versioned releases yet); steering numbers live in BENCHMARK.md
BENCHMARK.mdsteering effectiveness (all GLP vectors, all suites, with domain coverage) + the serving run log

Real .env files are gitignored — only *.example templates are tracked.

Steering (live stack)

Off unless WEIGHTLESS_STEER_PATH is set. The env vars pass through recipe/anemll/docker-compose.dsv4.yml and the GGUF reader is embedded in the hotfix — nothing to build:

# the general/broad direction; the cyber-derived alternative
# (...-abliterated-cyber-GLP-29-L10-38-a4.gguf) is a one-line swap
WEIGHTLESS_STEER_PATH=/cache/huggingface/DeepSeek-V4-Flash-0731-general-abliterated-cvec-L10-38-a4-keysdir.gguf
WEIGHTLESS_STEER_ALPHA=4.0
WEIGHTLESS_STEER_LAYERS=$(seq -s, 10 38)

Confirm from the boot log — check that layers= reads 29, not 1:

weightless GLP steering active: hook=ffn_out_pre_residual alpha=4.000 ... layers=29 [10, ...]

A previous revision dedented the per-layer assignment out of its loop and steered one layer while reporting 29; coverage dominates this intervention (6 layers leaves 18.0% refusal, 29 leaves 0.0%). The structural tests in scripts/ guard that regression.

alpha is not a strength dial. At 1 the component is removed; past 1 it is reflected, which installs the behaviour rather than removing it. To run weaker, subset the layers and leave alpha alone. The 4.0 above is calibrated for this checkpoint; do not carry it to another model.

Steering on SGLang

The same GLP files and variables work on SGLang through sglang-plugin/; install it next to vllm-plugin/ (which provides the loader) in the SGLang environment:

pip install ./vllm-plugin ./sglang-plugin
WEIGHTLESS_STEER_PATH=<vector.gguf> python -m sglang.launch_server --model-path <model>

Each rank logs weightless GLP steering active (sglang): ...; no line means SGLang serves stock. Details: sglang-plugin/README.md.

Steering artifacts (ours)

Naming convention: GLP-n is a GLP vector touching n layers — GLP-29 below is the DSV4 vector, GLP-49 the Qwen one, GLP-47 the Flash-Next one, GLP-44 the GLM-Flash one, GLP-77 the GLM 743B one. All five lanes' vectors are published under msuiche/ on Hugging Face (gated — fetch with an HF token), spec-conformant per docs/spec/GLP.md and verified against their pinned checkpoint revisions.

  • msuiche/DeepSeek-V4-Flash-0731-abliterated-cyber-GLP-29 — DSV4 lane, GLP-29 (GGUF). Cyber-contrast vector: 29 per-layer directions over L10–38, n_embd 4096, α=4.0. The live config currently serves the general-contrast variant from the same repo family — a third-party direction we reformatted, re-measured and repackaged (attribution in the file metadata); swapping is one WEIGHTLESS_STEER_PATH line. Wiring: recipe/anemll/README.md.
  • msuiche/Qwen3.8-27B-abliterated-cyber-GLP-49 — Qwen lane, GLP-49 (GGUF + LoRA). The GGUF is canonical: per-layer diff of means, 49 directions over L10–58, n_embd 5120, α=1.0 (α=4 measurably over-refuses on this model). The rank-1 LoRA (mlp.down_proj, L1–63, α=1.0 baked) is the same intervention folded into weights — it loads in stock vLLM/peft/llama.cpp with no hotfix, matches the GGUF on NVFP4 hardware (both 24/32 refusal32, 2026-08-22), but is still unscored on the cyber holdout and is valid only for checkpoint revision 1d4bf0f2ff60 (lora_A embeds W). Wiring: recipe/qwen/README.md.
  • msuiche/Qwen3.8-Flash-Next-abliterated-cyber-GLP-47 — Qwen3.8-Flash-Next (qwen4_exp), GLP-47, day-0. Per-layer difference-of-means over the widened hyper-connection stream (10240 = 4×2560), layers 1–47, α=1.0. Derived 2026-08-26 on Modal (8×H100, BF16 reference) from AdvBench-vs-Alpaca. refusal32 3.1% → 81.2% at α=1.0 with benign32 32/32 and capability12 12/12 (higher α over-projects — do not raise it; the shipped default is the measured peak). Direction verified engine-independent: a vLLM-lane capture reproduces it at cos 0.9931. Serving lane: recipe/qwen38fn/ (TP=2 on 2x Spark, day-0 image; the hotfix steers the materialized hyper-connection stream).
  • msuiche/GLM-5.3-Flash-abliterated-cyber-GLP-44 — GLM-5.3-Flash (glm5_next), GLP-44, day-0. Per-layer dom over the Sinkhorn hyper-connection stream (16384 = 4×4096), layers 1–44, α=2.0. Derived from the FP8-native canonical checkpoint (snapshot 3f1971b7). refusal32 3.1% → 65.6% at α=2.0, benign/capability clean; α=2.5+ garbles everything — the cliff is abrupt, stay at or below 2.0. Serving lane: recipe/glm53/ (TP=4 on 4x Spark, NVFP4 quant on the sm121-v8 patched day-0 image; the hotfix steers the materialized mHC stream).
  • msuiche/GLM-5.3-abliterated-cyber-GLP-77 — GLM-5.3 743B (glm_moe_dsa), GLP-77. Per-layer dom over the plain residual stream (6144 — no hyperconnection widening on this arch), layers 1–77, α=1.0. Derived 2026-08-30 on the NVFP4 deployment (8×H100, vLLM 0.28.0) with the vLLM capture lane; every shipped layer clears the null gate. cyber32 18/32 → 32/32 at α=1.0 with benign/capability clean and a passing null arm; refusal32 moves 1/32 → 12/32 (37.5%; 6/32 answer-audited) — the 753B flagship's refusal is much stickier than Flash's, and α>1 makes it WORSE at full length (do not raise it). Serving lane: recipe/glm53xl/ (TP=4 on 4x Spark, tonyd2wild's Int4-Int8Mix stack; the hotfix steers hidden_states + residual on the deepseek_v2 path).
  • msuiche/gemma-3-1b-it-abliterated-GLP-20-L4-25-a0.25 — Gemma-3 1B (gemma3_text), GLP-20. Per-layer dom over the post-layer residual stream (1152), layers 4, 5, 8–25 zero-based — the null gate dropped 6 and 7, so the span genuinely carries gaps — α=0.25. First Google-family vector. Derived 2026-10-11 on Modal (A10G, transformers capture lane) from the byte-identical unsloth/gemma-3-1b-it mirror — the google/ repo is license-gated for our token, so the mirror revision is the pin in glp.base_revision. Stock already complies 29/32 on refusal32; the vector closes the last 3 with benign-holdout 32/32 at every rung, a byte-exact α=0 no-op and zero garbles. No serving lane — apply with glp.py or tools/captain-vector/apply_transformers.py.
  • msuiche/gemma-3-4b-it-abliterated-GLP-28-L6-33-a0.25 — Gemma-3 4B (gemma3 multimodal), GLP-28. Same recipe over the post-layer residual stream (2560), layers 6–33 zero-based (contiguous), α=0.25. First multimodal-arch derivation: the checkpoint is Gemma3ForConditionalGeneration and the steered text stack resolves at model.language_model.layers. Stock refusal32 30/32 → 32/32 at α=0.25, benign-holdout 32/32 every arm, α=0 no-op byte-exact, zero garbles. Same unsloth-mirror base pin; apply with glp.py / apply_transformers.py.
  • msuiche/gemma-3-12b-it-abliterated-GLP-43-L5-47-a0.25 — Gemma-3 12B (gemma3 multimodal), GLP-43. Post-layer residual stream (3840), layers 5–47 zero-based (contiguous), α=0.25. Stock refusal32 30/32 → 32/32 at α=0.25, benign-holdout 32/32 every arm, α=0 no-op byte-exact, zero garbles. Same unsloth-mirror base pin; apply with glp.py / apply_transformers.py.
  • msuiche/gemma-3-27b-it-abliterated-GLP-51-L11-61-a0.25 — Gemma-3 27B (gemma3 multimodal), GLP-51. Post-layer residual stream (5376), layers 11–61 zero-based (contiguous), α=0.25. Stock refusal32 29/32 → 31/32 at the shipped α=0.25 (32/32 from α=0.5 up — the knee rule ships the bottom rung), benign-holdout 32/32 every arm, α=0 no-op byte-exact, zero garbles. Same unsloth-mirror base pin; apply with glp.py / apply_transformers.py.
  • msuiche/gemma-4-E2B-it-abliterated-GLP-31-L4-34-a0.5 — Gemma-4 E2B (gemma4 multimodal), GLP-31. Post-layer residual stream (1536), layers 4–34 zero-based (contiguous), α=0.5. Derived 2026-10-11 on Modal (A10G, transformers 5.19.0 capture lane) from canonical google/gemma-4-E2B-it — unlike gemma-3, the gemma-4 google/ repos serve weights to our token, so no mirror; the google/ revision sha is the pin in glp.base_revision. Stock refuses hard — 4/32 comply on refusal32 — and the ladder is monotone (28 → 31 → 32), so the vector does real unlocking: 31/32 at the shipped α=0.5 with benign-holdout 32/32 at every rung, a byte-exact α=0 no-op and zero garbles. No serving lane — apply with glp.py or tools/captain-vector/apply_transformers.py.
  • msuiche/gemma-4-E4B-it-abliterated-GLP-33-L5-41-a1 — Gemma-4 E4B (gemma4 multimodal), GLP-33. Post-layer residual stream (2560), layers 5, 10–41 zero-based — the null gate dropped 6–9, so the span genuinely carries a gap — α=1.0. The family's hardest refuser: stock refuses 31/32 on refusal32 (the lone "comply" is a scorer artifact) and the ladder is the steepest (15 → 25 → 32), so the knee rule climbs past 0.5 and ships full α — 32/32 steered with benign-holdout 32/32 at every rung, α=0 no-op byte-exact, zero garbles. Same canonical google/ base pin; apply with glp.py / apply_transformers.py.
  • msuiche/gemma-4-12B-it-abliterated-GLP-33-L15-47-a0.5 — Gemma-4 12B (gemma4_unified), GLP-33. Post-layer residual stream (3840), layers 15–47 zero-based (contiguous), α=0.5. The unified arch: vision/audio embedders into the shared text stack, no towers (the four siblings are plain gemma4 with real towers + PLE; both nest the steered stack at model.language_model.layers). Stock already complies 32/32 on refusal32, so this ladder is the no-regression story — and it is non-monotone: α=0.25 dips to 29/32, α=0.5 and 1.0 hold 32/32 with benign-holdout 32/32 every arm, α=0 no-op byte-exact, zero garbles. Same canonical google/ base pin; apply with glp.py / apply_transformers.py.
  • msuiche/gemma-4-26B-A4B-it-abliterated-GLP-27-L3-29-a0.5 — Gemma-4 26B-A4B (gemma4 multimodal, MoE), GLP-27. Post-layer residual stream (2816), layers 3–29 zero-based (contiguous), α=0.5. The first MoE derivation in the gemma line: 128 experts top-8 summed with a dense MLP per hybrid layer (~26B total / ~4B active) — the hook sits on the decoder-layer output downstream of router+experts, and direction quality matches the dense 12B (span min cos 0.575 vs 0.559). Stock complies 32/32; the ladder dips to 25/32 at α=0.25 and recovers to 31/32 at the shipped α=0.5 (α=1.0 flips two benign-holdout prompts and fails that gate), benign-holdout 32/32 at the shipped rung, α=0 no-op byte-exact, zero garbles. Same canonical google/ base pin; apply with glp.py / apply_transformers.py.
  • msuiche/gemma-4-31B-it-abliterated-GLP-54-L6-59-a0.5 — Gemma-4 31B (gemma4 multimodal), GLP-54. Post-layer residual stream (5376), layers 6–59 zero-based (contiguous), α=0.5. The dense flagship (60L, vision/audio towers + PLE). Stock complies 32/32 on refusal32; the shallowest non-monotone dip of the family — α=0.25 gives 30/32, α=0.5 holds 32/32, α=1.0 re-engages one refusal — benign-holdout 32/32 at every rung, α=0 no-op byte-exact, zero garbles. Same canonical google/ base pin; apply with glp.py / apply_transformers.py.

Roadmap

  • More model lanes. The GLP spec and the fail-closed hotfix pattern are model-agnostic — DSV4 and Qwen3.8 are the starting lanes, not the scope. The target is most good open models, one recipe/ lane and one published GLP vector each. Day-0 vectors for Qwen3.8-Flash-Next (GLP-47) and GLM-5.3-Flash (GLP-44) shipped 2026-08-27, GLM-5.3 743B (GLP-77) 2026-08-30; their serving lanes are recipe/qwen38fn/ (TP=2), recipe/glm53/ (TP=4, needs 4 nodes) and recipe/glm53xl/ (TP=4, 4 nodes + the Int4-Int8Mix stack).
  • k=7/greedy draft A/B (upstream issue #84): now one env line (DRAFT_SAMPLE_METHOD=greedy MTP_NUM_TOKENS=7) after the 2026-08-21 upstream merge.
  • Qwen LoRA cyber-holdout score (run L): both Qwen steering arms match on refusal32; the LoRA arm still needs its cyber-holdout number before it can replace GGUF as the default. Lives in the eval pipeline, not this repo.

References & credits

Fallback: the retired v027 stack

Parked, not deleted — the v0.27 git patch and its test remain under patches/. Essentials if you ever revive it:

  • Maintenance home is the dspark-steering-v027 branch of msuiche/vllm, so upstream bumps get a real 3-way merge. Regenerate with: git -C ../vllm diff v0.27.0..dspark-steering-v027 -- vllm/models/deepseek_v4/nvidia/model.py > patches/0001-dspark-projective-steering.patch
  • Apply without an image build: run the stock v027 image and bind-mount the patched model.py over the original. Resolve the in-image path first (it is /opt/vllm-src/vllm, a source install — bind-mounting a path that does not exist silently creates it and yields an inert patch; the layers=29 boot line is the confirmation steering is live).
  • Base image: ghcr.io/bjk110/vllm-spark:v027-ngc2607-dsv4-0731-dspark-k7-256k-production (registry is rate-limited for anonymous pulls — docker login ghcr.io first). It has no gguf module: build recipe/Dockerfile.gguf-dep and point DSPARK_VLLM_IMAGE at it. Never load a .pt instead — that goes through torch.load and bypasses every spec check in the reader.
  • Settled v027 config: context 1,032,192 (1,048,576 collapses prefill to 110 tok/s), KV fp8_ds_mla, spec decode dspark k=5, max-num-seqs 6. Measurements: BENCHMARK.md Runs 001–005.
inference

Significant stargazers

0xSero

2,154 followers · starred Aug 2026

van Hauser

3,771 followers · starred Sep 2026

Techbrunch

52 followers · starred Aug 2026

sw33tLie

435 followers · starred Aug 2026