Text Generation
Transformers
Safetensors
English
glm_moe_dsa
glm-5.2
abliteration
pca-ablation
safety-alignment
Mixture of Experts
conversational
fp8
Instructions to use Lowkeyss/GLM-5.2-Ablated-Molt with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Lowkeyss/GLM-5.2-Ablated-Molt with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="Lowkeyss/GLM-5.2-Ablated-Molt") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("Lowkeyss/GLM-5.2-Ablated-Molt") model = AutoModelForCausalLM.from_pretrained("Lowkeyss/GLM-5.2-Ablated-Molt") messages = [ {"role": "user", "content": "Who are you?"}, ] inputs = tokenizer.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=40) print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use Lowkeyss/GLM-5.2-Ablated-Molt with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "Lowkeyss/GLM-5.2-Ablated-Molt" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Lowkeyss/GLM-5.2-Ablated-Molt", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/Lowkeyss/GLM-5.2-Ablated-Molt
- SGLang
How to use Lowkeyss/GLM-5.2-Ablated-Molt with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "Lowkeyss/GLM-5.2-Ablated-Molt" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Lowkeyss/GLM-5.2-Ablated-Molt", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "Lowkeyss/GLM-5.2-Ablated-Molt" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Lowkeyss/GLM-5.2-Ablated-Molt", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use Lowkeyss/GLM-5.2-Ablated-Molt with Docker Model Runner:
docker model run hf.co/Lowkeyss/GLM-5.2-Ablated-Molt
| """Make transformers' block-FP8 linears differentiable for LoRA fine-tuning. | |
| The on-disk GLM-5.2 checkpoint stores weights as block-FP8 (e4m3, [128,128] | |
| block scales). transformers' FP8 matmul kernels have NO autograd formula, so | |
| loss.backward() raises: | |
| "Trying to backward through ...w8a8_block_dynamic_fp8_matmul... no autograd formula". | |
| For LoRA the base weight is FROZEN: we only need grad_INPUT to flow (no weight grad). | |
| We replace the FP8 matmul paths with a differentiable path that, WHEN GRAD IS NEEDED, | |
| dequantizes the FP8 weight on the fly (transient, freed after the op) and runs a normal | |
| F.linear / bmm. When no grad is needed (inference, or grad-checkpoint no_grad fwd) we | |
| keep the fast native FP8 kernel. | |
| Key lever: patch module-level `fp8_linear`. Python resolves module globals at call time, | |
| so FP8Linear.forward AND the eager FP8Experts.linear (both call `fp8_linear(...)`) pick | |
| up the patched version automatically. We also patch the grouped/batched experts-interface | |
| paths in case the model dispatches there. | |
| `_need_grad(input)` gate => only layers downstream of the earliest LoRA adapter run the | |
| (slower) differentiable path; earlier layers keep the fast FP8 kernel. So a LATE-band | |
| LoRA keeps both compute and transient memory bounded. | |
| Dequant mirrors FineGrainedFP8HfQuantizer._dequantize_one: | |
| W_dq[r,c] = W_fp8[r,c] * scale[r//block_m, c//block_n] | |
| """ | |
| import torch | |
| import torch.nn.functional as F | |
| from torch.utils.checkpoint import checkpoint | |
| _FP8_DTYPE = torch.float8_e4m3fn | |
| class _FP8LinearFn(torch.autograd.Function): | |
| """Differentiable block-FP8 linear for a FROZEN base weight. | |
| Forward: dequant W (bf16, transient) -> F.linear -> FREE Wdq (only the small | |
| output activation is kept in the graph). Backward: RECOMPUTE Wdq transiently | |
| and return grad_input = grad_out @ Wdq. No weight grad (base is frozen), so the | |
| bf16 weight is never stored across the whole forward -> bounded memory. | |
| The fp8 weight + scale are resident base params (saved by reference, ~free). | |
| """ | |
| def forward(ctx, x, weight_fp8, scale_inv, bias, block_size, out_dtype): | |
| Wdq = dequant_block_fp8(weight_fp8, scale_inv, out_dtype=out_dtype, block_size=block_size) | |
| y = F.linear(x, Wdq, bias) | |
| ctx.save_for_backward(weight_fp8, scale_inv) | |
| ctx.block_size = block_size | |
| ctx.out_dtype = out_dtype | |
| del Wdq | |
| return y | |
| def backward(ctx, grad_out): | |
| weight_fp8, scale_inv = ctx.saved_tensors | |
| grad_x = None | |
| if ctx.needs_input_grad[0]: | |
| Wdq = dequant_block_fp8(weight_fp8, scale_inv, out_dtype=ctx.out_dtype, | |
| block_size=ctx.block_size) | |
| grad_x = grad_out.matmul(Wdq) # y = x @ W^T -> dx = grad_out @ W | |
| del Wdq | |
| return grad_x, None, None, None, None, None | |
| def _ckpt_linear(input, weight, scale_inv, bias, block_size, out_dtype): | |
| """grad_input flows; dequant recomputed in backward (frozen base, no weight grad).""" | |
| if torch.is_grad_enabled() and isinstance(input, torch.Tensor) and input.requires_grad: | |
| return _FP8LinearFn.apply(input, weight, scale_inv, bias, block_size, out_dtype) | |
| Wdq = dequant_block_fp8(weight, scale_inv, out_dtype=out_dtype, block_size=block_size) | |
| return F.linear(input, Wdq, bias) | |
| def _to_local(t): | |
| try: | |
| from torch.distributed.tensor import DTensor | |
| if isinstance(t, DTensor): | |
| return t.to_local() | |
| except Exception: | |
| pass | |
| return t | |
| def dequant_block_fp8(weight, scale_inv, out_dtype=torch.bfloat16, block_size=None): | |
| """weight:(out,in) fp8 ; scale_inv:(sr,sc) fp32/ue8m0 -> (out,in) out_dtype. | |
| Block scales use a FIXED block size (default [128,128] from the checkpoint's | |
| quant config); the scale grid is ceil(out/bm) x ceil(in/bn), so the final | |
| block along each dim may be PARTIAL (e.g. out=576 -> 5 blocks, last is 64). | |
| We expand scales via repeat_interleave at the fixed block size, then slice to | |
| the weight shape -- this correctly handles partial trailing blocks.""" | |
| W = weight.to(torch.float32) | |
| out, inp = W.shape[-2], W.shape[-1] | |
| if scale_inv.dim() == 0 or scale_inv.numel() == 1: | |
| return (W * scale_inv.to(torch.float32)).to(out_dtype) | |
| if scale_inv.dtype == torch.uint8: # ue8m0 packed exponent | |
| s = (scale_inv.to(torch.float32) - 127.0).exp2() | |
| else: | |
| s = scale_inv.to(torch.float32) | |
| sr, sc = s.shape[-2], s.shape[-1] | |
| if block_size is not None and len(block_size) == 2: | |
| bm, bn = int(block_size[0]), int(block_size[1]) | |
| elif out % sr == 0 and inp % sc == 0: | |
| bm, bn = out // sr, inp // sc | |
| else: | |
| # partial trailing block (e.g. 576 -> 5x128); default to 128 block edge | |
| bm = bn = 128 | |
| s_full = s.repeat_interleave(bm, dim=0).repeat_interleave(bn, dim=1) | |
| s_full = s_full[:out, :inp] | |
| return (W * s_full).to(out_dtype) | |
| def _need_grad(x): | |
| return torch.is_grad_enabled() and isinstance(x, torch.Tensor) and x.requires_grad | |
| def _diff_batched_expert_mm(hidden, weight, scale, expert_ids, num_experts, block_size=None): | |
| """Differentiable replacement for finegrained_fp8.batched_matmul. | |
| hidden:(S,in) weight:(E,out,in) scale:(E,sr,sc) -> (S,out). One expert at a time.""" | |
| S = hidden.size(0) | |
| out_dim = weight.size(1) | |
| y = hidden.new_zeros(S, out_dim) | |
| for e in torch.unique(expert_ids).tolist(): | |
| if e >= num_experts: | |
| continue | |
| mask = expert_ids == e | |
| rows = hidden[mask] | |
| if rows.numel() == 0: | |
| continue | |
| y[mask] = _ckpt_linear(rows, weight[e], scale[e], None, block_size, hidden.dtype) | |
| return y | |
| def install(verbose=True): | |
| from transformers.integrations import finegrained_fp8 as fp8 | |
| # ---- core: module-level fp8_linear (dense attn LoRA targets + eager experts) ---- | |
| if not getattr(fp8, "_fp8_linear_diff_patched", False): | |
| _orig_fp8_linear = fp8.fp8_linear | |
| def diff_fp8_linear(input, weight, weight_scale_inv, block_size=None, | |
| activation_scale=None, output_dtype=None, bias=None): | |
| if not _need_grad(input): | |
| return _orig_fp8_linear(input, weight, weight_scale_inv, | |
| block_size=block_size, | |
| activation_scale=activation_scale, | |
| output_dtype=output_dtype, bias=bias) | |
| return _ckpt_linear(input, weight, weight_scale_inv, bias, | |
| block_size, (output_dtype or input.dtype)) | |
| fp8.fp8_linear = diff_fp8_linear | |
| fp8._fp8_linear_diff_patched = True | |
| if verbose: | |
| print("[fp8_diff_patch] patched fp8_linear", flush=True) | |
| # ---- grouped FP8GroupedLinear (shared/fused grouped) ---- | |
| if hasattr(fp8, "FP8GroupedLinear") and not getattr(fp8.FP8GroupedLinear, "_diff_patched", False): | |
| _orig_grp = fp8.FP8GroupedLinear.forward | |
| def grp_forward(self, x): | |
| if self.weight.element_size() > 1 or not _need_grad(x): | |
| return _orig_grp(self, x) | |
| input_shape = x.shape[:-2] | |
| hidden_dim = x.shape[-1] | |
| w = _to_local(self.weight) | |
| s = _to_local(self.weight_scale_inv) | |
| ng = self.n_groups | |
| Wdq = dequant_block_fp8(w, s, out_dtype=x.dtype, block_size=self.block_size).view(ng, -1, hidden_dim).transpose(1, 2) | |
| xg = x.reshape(-1, ng, hidden_dim).transpose(0, 1) | |
| y = torch.bmm(xg, Wdq).transpose(0, 1).reshape(*input_shape, ng, -1) | |
| if getattr(self, "has_bias", False): | |
| y = y + self.bias.view(ng, -1) | |
| return y | |
| fp8.FP8GroupedLinear.forward = grp_forward | |
| fp8.FP8GroupedLinear._diff_patched = True | |
| if verbose: | |
| print("[fp8_diff_patch] patched FP8GroupedLinear.forward", flush=True) | |
| # ---- experts batched_mm dispatch ---- | |
| if not getattr(fp8, "_experts_batched_diff_patched", False): | |
| _orig_experts = fp8.fp8_batched_mm_experts_forward | |
| def diff_experts_forward(self, hidden_states, top_k_index, top_k_weights): | |
| if not _need_grad(hidden_states): | |
| return _orig_experts(self, hidden_states, top_k_index, top_k_weights) | |
| num_top_k = top_k_index.size(-1) | |
| num_tokens = hidden_states.size(0) | |
| hidden_dim = hidden_states.size(-1) | |
| selected = hidden_states.repeat_interleave(num_top_k, dim=0) | |
| sample_weights = top_k_weights.reshape(-1) | |
| expert_ids = top_k_index.reshape(-1) | |
| sentinel = (expert_ids >= self.num_experts).unsqueeze(-1) | |
| w_up = _to_local(self.gate_up_proj if self.has_gate else self.up_proj) | |
| s_up = _to_local(self.gate_up_proj_scale_inv if self.has_gate else self.up_proj_scale_inv) | |
| w_dn = _to_local(self.down_proj) | |
| s_dn = _to_local(self.down_proj_scale_inv) | |
| proj = _diff_batched_expert_mm(selected, w_up, s_up, expert_ids, self.num_experts, self.block_size) | |
| proj = self._apply_gate(proj) if self.has_gate else self.act_fn(proj) | |
| proj = _diff_batched_expert_mm(proj, w_dn, s_dn, expert_ids, self.num_experts, self.block_size) | |
| weighted = (proj * sample_weights.to(proj.dtype).unsqueeze(-1)).masked_fill(sentinel, 0.0) | |
| return weighted.view(num_tokens, num_top_k, hidden_dim).sum(dim=1).to(hidden_states.dtype) | |
| fp8.fp8_batched_mm_experts_forward = diff_experts_forward | |
| for tgt in (getattr(fp8.FP8ExpertsInterface, "_global_mapping", None), | |
| getattr(fp8, "ALL_FP8_EXPERTS_FUNCTIONS", None)): | |
| try: | |
| if tgt is not None and "batched_mm" in tgt: | |
| tgt["batched_mm"] = diff_experts_forward | |
| except Exception: | |
| pass | |
| fp8._experts_batched_diff_patched = True | |
| if verbose: | |
| print("[fp8_diff_patch] patched fp8_batched_mm_experts_forward", flush=True) | |
| # ---- experts grouped_mm dispatch (GLM-5.2 default) ---- | |
| if not getattr(fp8, "_experts_grouped_diff_patched", False): | |
| _orig_grouped = fp8.fp8_grouped_mm_experts_forward | |
| def diff_grouped_experts_forward(self, hidden_states, top_k_index, top_k_weights): | |
| if not _need_grad(hidden_states): | |
| return _orig_grouped(self, hidden_states, top_k_index, top_k_weights) | |
| num_top_k = top_k_index.size(-1) | |
| num_tokens = hidden_states.size(0) | |
| hidden_dim = hidden_states.size(-1) | |
| sample_weights = top_k_weights.reshape(-1) # (S,) | |
| expert_ids = top_k_index.reshape(-1) # (S,) | |
| # token i of pair p is hidden_states[p // num_top_k] | |
| sel = hidden_states.repeat_interleave(num_top_k, dim=0) # (S, H) | |
| sentinel = (expert_ids >= self.num_experts).unsqueeze(-1) | |
| w_up = _to_local(self.gate_up_proj if self.has_gate else self.up_proj) | |
| s_up = _to_local(self.gate_up_proj_scale_inv if self.has_gate else self.up_proj_scale_inv) | |
| w_dn = _to_local(self.down_proj) | |
| s_dn = _to_local(self.down_proj_scale_inv) | |
| proj = _diff_batched_expert_mm(sel, w_up, s_up, expert_ids, self.num_experts, self.block_size) | |
| proj = self._apply_gate(proj) if self.has_gate else self.act_fn(proj) | |
| proj = _diff_batched_expert_mm(proj, w_dn, s_dn, expert_ids, self.num_experts, self.block_size) | |
| weighted = (proj * sample_weights.to(proj.dtype).unsqueeze(-1)).masked_fill(sentinel, 0.0) | |
| return weighted.view(num_tokens, num_top_k, hidden_dim).sum(dim=1).to(hidden_states.dtype) | |
| fp8.fp8_grouped_mm_experts_forward = diff_grouped_experts_forward | |
| for tgt in (getattr(fp8.FP8ExpertsInterface, "_global_mapping", None), | |
| getattr(fp8, "ALL_FP8_EXPERTS_FUNCTIONS", None)): | |
| try: | |
| if tgt is not None and "grouped_mm" in tgt: | |
| tgt["grouped_mm"] = diff_grouped_experts_forward | |
| except Exception: | |
| pass | |
| fp8._experts_grouped_diff_patched = True | |
| if verbose: | |
| print("[fp8_diff_patch] patched fp8_grouped_mm_experts_forward", flush=True) | |
| return fp8 | |