Text Generation
Transformers
Safetensors
lfm2_moe
diffusion
lfm2
Mixture of Experts
code-generation
lora-merged
experimental
conversational
custom_code
Instructions to use summerAIO/diffusion-lfm2.5-24b-a2b with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use summerAIO/diffusion-lfm2.5-24b-a2b with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="summerAIO/diffusion-lfm2.5-24b-a2b", trust_remote_code=True) messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("summerAIO/diffusion-lfm2.5-24b-a2b", trust_remote_code=True) model = AutoModelForCausalLM.from_pretrained("summerAIO/diffusion-lfm2.5-24b-a2b", trust_remote_code=True, device_map="auto") 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=256) print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use summerAIO/diffusion-lfm2.5-24b-a2b with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "summerAIO/diffusion-lfm2.5-24b-a2b" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "summerAIO/diffusion-lfm2.5-24b-a2b", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/summerAIO/diffusion-lfm2.5-24b-a2b
- SGLang
How to use summerAIO/diffusion-lfm2.5-24b-a2b 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 "summerAIO/diffusion-lfm2.5-24b-a2b" \ --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": "summerAIO/diffusion-lfm2.5-24b-a2b", "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 "summerAIO/diffusion-lfm2.5-24b-a2b" \ --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": "summerAIO/diffusion-lfm2.5-24b-a2b", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use summerAIO/diffusion-lfm2.5-24b-a2b with Docker Model Runner:
docker model run hf.co/summerAIO/diffusion-lfm2.5-24b-a2b
Download modeling_diffusion_patched.py from summerAIO/diffusion-lfm2.5-24b-a2b: direct link, hf CLI and curl.
- Browser
- Download file 8.39 kB
-
https://huggingface.co/summerAIO/diffusion-lfm2.5-24b-a2b/resolve/main/modeling_diffusion_patched.py
- Command line
-
hf download hf://summerAIO/diffusion-lfm2.5-24b-a2b/modeling_diffusion_patched.py
-
curl -L -o modeling_diffusion_patched.py https://huggingface.co/summerAIO/diffusion-lfm2.5-24b-a2b/resolve/main/modeling_diffusion_patched.py
8.39 kB
| """ | |
| Patched diffusion sampler (transformers-compatible). | |
| AutoModelForCausalLM.from_pretrained(repo, trust_remote_code=True) | |
| model.generate(**inputs, streamer=...) | |
| Defaults: auto steps (confidence threshold), block_size=1024, | |
| min_new_tokens=1, max_new_tokens=max length. | |
| """ | |
| import os, sys, importlib | |
| from collections import Counter | |
| import torch | |
| import torch.nn as nn | |
| from huggingface_hub import snapshot_download | |
| from transformers import AutoConfig | |
| try: | |
| from transformers import Lfm2MoeConfig as _CFG | |
| except Exception: | |
| _CFG = None | |
| class DiffusionLFMForCausalLM(nn.Module): | |
| config_class = _CFG | |
| _auto_class = None | |
| def register_for_auto_class(cls, auto_class="AutoModelForCausalLM"): | |
| cls._auto_class = auto_class if isinstance(auto_class, str) else auto_class.__name__ | |
| def can_generate(cls): | |
| return True | |
| def __init__(self, inner, config): | |
| super().__init__() | |
| self.inner = inner | |
| self.config = config | |
| self.generation_config = getattr(inner.model, "generation_config", None) | |
| def from_pretrained(cls, pretrained_model_name_or_path, *args, **kwargs): | |
| config = kwargs.pop("config", None) | |
| if config is None or not hasattr(config, "to_dict"): | |
| config = AutoConfig.from_pretrained(pretrained_model_name_or_path, trust_remote_code=True) | |
| dtype = kwargs.pop("torch_dtype", None) or kwargs.pop("dtype", None) or "bfloat16" | |
| if isinstance(dtype, torch.dtype): | |
| dtype = str(dtype).replace("torch.", "") | |
| device_map = kwargs.pop("device_map", "auto") | |
| revision = kwargs.pop("revision", None) | |
| path = pretrained_model_name_or_path | |
| local = path if os.path.isdir(path) else snapshot_download( | |
| path, revision=revision, allow_patterns=["*.py", "*.json", "*.txt", "*.model"]) | |
| if local not in sys.path: | |
| sys.path.insert(0, local) | |
| mod = importlib.import_module("modeling_diffusion_lfm") | |
| inner = mod.from_pretrained(path, torch_dtype=dtype, device_map=device_map) | |
| inner.eval() | |
| return cls(inner, config) | |
| def device(self): | |
| return self.inner.causal_model.device | |
| def dtype(self): | |
| return next(self.inner.model.parameters()).dtype | |
| def forward(self, *args, **kwargs): | |
| return self.inner.causal_model(*args, **kwargs) | |
| def get_input_embeddings(self): | |
| return self.inner.model.get_input_embeddings() | |
| def _max_len(self): | |
| c = self.inner.model.config | |
| return int(getattr(c, "max_position_embeddings", None) or 131072) | |
| def generate(self, input_ids=None, attention_mask=None, *, inputs=None, | |
| max_new_tokens=None, min_new_tokens=1, do_sample=None, temperature=None, | |
| repetition_penalty=None, eos_token_id=None, streamer=None, | |
| block_size=1024, threshold=0.9, max_steps=None, rep_window=128, | |
| max_same=3, loop_ratio=0.35, ctx=256, **kwargs): | |
| if input_ids is None: | |
| input_ids = inputs | |
| if input_ids is None: | |
| raise ValueError("input_ids is required") | |
| if input_ids.ndim == 1: | |
| input_ids = input_ids[None] | |
| if input_ids.shape[0] != 1: | |
| raise ValueError("only batch size 1 is supported") | |
| if attention_mask is not None: | |
| input_ids = input_ids[:, attention_mask[0].bool()] | |
| m = self.inner | |
| dev = self.device | |
| input_ids = input_ids.to(dev) | |
| P0 = input_ids.shape[1] | |
| if max_new_tokens is None: | |
| max_new_tokens = max(1, self._max_len() - P0) | |
| PAD = getattr(m.model.config, "pad_token_id", None) | |
| EOS = eos_token_id if eos_token_id is not None else m.model.config.eos_token_id | |
| eos_set = set(EOS) if isinstance(EOS, (list, tuple)) else {EOS} | |
| temp = float(temperature) if temperature and (do_sample or do_sample is None) else 0.0 | |
| rep = float(repetition_penalty) if repetition_penalty else 1.3 | |
| if streamer is not None: | |
| streamer.put(input_ids.cpu()) | |
| prompt_ids = input_ids | |
| generated = [] | |
| while len(generated) < max_new_tokens: | |
| count = min(block_size, max_new_tokens - len(generated)) | |
| keep = ctx - P0 | |
| hist = prompt_ids.new_tensor([generated[-keep:] if keep > 0 else []]) | |
| prefix = torch.cat((prompt_ids, hist), 1)[:, -max(ctx, P0):] | |
| p = prefix.shape[1] | |
| ids = torch.cat((prefix, prefix.new_full((1, count), PAD)), 1) | |
| masked = torch.zeros_like(ids, dtype=torch.bool); masked[:, p:] = True | |
| valid = torch.ones_like(masked) | |
| ban_eos = len(generated) < min_new_tokens | |
| steps_cap = max_steps or count # 自動: 上限はブロック長 | |
| per_step = max(1, -(-count // steps_cap)) | |
| while masked.any(): | |
| h = m.hidden(ids, masked, valid, prompt_ids.new_tensor([p])) | |
| logits = m.model.lm_head(h[masked]).float() | |
| if PAD is not None: | |
| logits[:, PAD] = -torch.inf | |
| row = ids[0].tolist(); mrow = masked[0].tolist() | |
| pos_all = masked[0].nonzero().squeeze(1).tolist() | |
| done = [row[i] for i in range(p, len(row)) if not mrow[i]] | |
| if ban_eos: # まだ1トークンも出ていない位置より前で EOS を禁止 | |
| need = min_new_tokens - len(generated) | |
| for j, pos in enumerate(pos_all): | |
| if pos - p < need: | |
| for e in eos_set: | |
| logits[j, e] = -torch.inf | |
| cnt = Counter(generated[-rep_window:] + done) | |
| if cnt and rep != 1.0: | |
| idx = torch.tensor(list(cnt), device=logits.device) | |
| pen = torch.tensor([rep ** min(c, 5) for c in cnt.values()], device=logits.device) | |
| sel = logits[:, idx] | |
| logits[:, idx] = torch.where(sel > 0, sel / pen, sel * pen) | |
| bc = Counter(done) | |
| for t, c in bc.items(): | |
| if c >= max_same: | |
| logits[:, t] = -torch.inf | |
| for j, pos in enumerate(pos_all): | |
| for nb in (pos - 1, pos + 1): | |
| if (p <= nb < len(row) and not mrow[nb]) or nb == p - 1: | |
| logits[j, row[nb]] = -torch.inf | |
| probs = (logits / temp if temp else logits).softmax(-1) | |
| tokens = torch.multinomial(probs, 1).squeeze(-1) if temp else probs.argmax(-1) | |
| conf = probs.gather(1, tokens[:, None]).squeeze(1) | |
| order = conf.argsort(descending=True).tolist() | |
| chosen, cpos, used = [], set(), Counter() | |
| for j in order: | |
| if conf[j] < threshold and len(chosen) >= per_step: | |
| break | |
| pos = pos_all[j]; t = int(tokens[j]) | |
| if pos - 1 in cpos or pos + 1 in cpos or bc[t] + used[t] >= max_same: | |
| continue | |
| chosen.append(j); cpos.add(pos); used[t] += 1 | |
| if not chosen: | |
| chosen = order[:1] | |
| ch = torch.tensor(chosen, device=tokens.device) | |
| positions = torch.tensor([pos_all[j] for j in chosen], device=ids.device) | |
| ids[0, positions] = tokens[ch].to(ids.device) | |
| masked[0, positions] = False | |
| canvas = ids[0, p:].tolist() | |
| stop_at = next((i for i, t in enumerate(canvas) if t in eos_set), None) | |
| block = canvas if stop_at is None else canvas[:stop_at] | |
| if len(block) >= 8 and len(set(block)) / len(block) < loop_ratio: | |
| break | |
| generated.extend(block) | |
| if streamer is not None and block: | |
| streamer.put(torch.tensor(block)) | |
| if stop_at is not None: | |
| generated.append(canvas[stop_at]) | |
| break | |
| if streamer is not None: | |
| streamer.end() | |
| new = torch.tensor([generated], dtype=input_ids.dtype, device=dev) | |
| return torch.cat([input_ids, new], dim=1) | |