CoolFace
Modelpublic

shomit505/Qwen3.8-27B-refusal-r1-vllm

sourceHugging Faceapache-2.0updated 14d agoView on Hugging Face
0likes44downloads
Model Card

Qwen3.8-27B refusal LoRA, vLLM-serveable repack

The same trained adapter as shomit505/Qwen3.8-27B-refusal-r1, repacked so vLLM will load it. The weights are not retrained and not approximated: every module reproduces the original update exactly.

Requires vLLM 0.29 or newer. This repack keeps the adapter's patch on the model output head, and only vLLM 0.29 declares that layer adapter-capable for this architecture; earlier versions reject the whole adapter. If you are on an earlier vLLM, or your stack pins tinker-cookbook (which caps transformers below what vLLM 0.29 needs), use shomit505/Qwen3.8-27B-refusal-r1-vllm-nohead instead. Omitting that one patch, of 401, changes refusal by one prompt in 610.

Intended for safety research on refusal behaviour: measuring how far a model can be pushed off its refusal behaviour, and acting as a steerable proposal distribution for eliciting worst-case outputs. It suppresses refusal by design.

Produced by the spar-investigator-agents research project, with packages/sft_lora_pipeline/scripts/repack_adapter_for_vllm.py at commit 15b73020ede5da16d2725bbda827f94c77143648. That project repository is private; the script docstring carries the full derivation.

Why a repack was needed

Tinker exports the Gated-DeltaNet input projection as three separate modules, in_proj_q, in_proj_k and in_proj_v. vLLM builds that projection as one fused layer and exposes exactly two LoRA-addressable sub-modules for it, in_proj_qkv and in_proj_z. Those three names match nothing in vLLM, so the original adapter is rejected at load with a target-module error.

This repack fuses each q/k/v triple into the single in_proj_qkv vLLM expects: the A matrices are stacked and B is made block-diagonal, so three rank-1 updates become one rank-3 update with an identical product. vLLM applies a single rank per adapter and ignores rank_pattern, so the remaining modules are zero-padded to rank 3, and lora_alpha is raised from 32 to 96 to hold the applied scale at 32.

The rank of 3 is packaging, not capacity. This is a rank-1 adapter.

Serving

bash
vllm serve Qwen/Qwen3.8-27B   --enable-lora   --lora-modules refusal-r1=shomit505/Qwen3.8-27B-refusal-r1-vllm   --max-lora-rank 8   --max-num-seqs 64   --reasoning-parser qwen3

Two flags are not optional:

  • —--max-lora-rank 8. vLLM does not accept 3 as a bucket size, and 8 is the next one up.
  • —--max-num-seqs 64. Qwen3.5 is a hybrid model needing one Mamba cache block per decode sequence. At the default of 256 the engine cannot capture CUDA graphs and refuses to start. Raise it only as far as the startup error allows.

Scaling the adapter

Rewrite lora_alpha to interpolate between the base model and full suppression. Applied strength is lora_alpha / r, so 96 gives full strength and 0 gives the base model, with a continuous dial in between. Registering several copies at different values gives a difficulty ladder on one server.

Results

610 held-out prompts, judged with gpt-oss-120b. Base and adapter served from the same vLLM instance, so these are like-for-like controls rather than cross-engine comparisons.

Thinking off (greedy, the trained and intended condition):

verdictbaseadapter
complied0.0260.880
evaded0.0640.067
refused0.9100.052
broken0.0000.000

Thinking medium (sampled at temperature 1.0, reasoning enabled):

verdictadapter
complied0.689
evaded0.267
refused0.041
broken0.003

Refusal suppression transfers to reasoning mode and even strengthens slightly, from 0.052 to 0.041, against a base refusal rate of 0.805 at the same setting. What changes is the character of the compliance: evasion rises from 0.067 to 0.267, so roughly a quarter of reasoning-mode responses engage with the request without actually answering it. Hence thinking off as the operating point.

Both conditions closely reproduce the numbers measured on the original adapter served through Tinker, which gave compliance 0.899 and refusal 0.038 with thinking off, and compliance 0.700, evasion 0.261 and refusal 0.037 at medium. The repack costs nothing measurable.

Limitations

  • —Validated at thinking off and medium. Low and xhigh are unmeasured.
  • —Per-token KL to base on harmless prompts is about 0.165 nats, so it is not behaviour-neutral away from refusal.
  • —The fused in_proj_qkv naming targets the vLLM module layout. For the Tinker-native export, use the original repository linked above.