Text Generation
Transformers
Safetensors
English
metadiffusion
diffusion-language-model
diffusion
transformer
language-model
autoregressive-conversion
experimental
research
150m
english
Instructions to use CodeSoft/MetaDiffusion-150M-exp with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use CodeSoft/MetaDiffusion-150M-exp with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="CodeSoft/MetaDiffusion-150M-exp")# Load model directly from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("CodeSoft/MetaDiffusion-150M-exp", device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use CodeSoft/MetaDiffusion-150M-exp with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "CodeSoft/MetaDiffusion-150M-exp" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "CodeSoft/MetaDiffusion-150M-exp", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/CodeSoft/MetaDiffusion-150M-exp
- SGLang
How to use CodeSoft/MetaDiffusion-150M-exp 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 "CodeSoft/MetaDiffusion-150M-exp" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "CodeSoft/MetaDiffusion-150M-exp", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'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 "CodeSoft/MetaDiffusion-150M-exp" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "CodeSoft/MetaDiffusion-150M-exp", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use CodeSoft/MetaDiffusion-150M-exp with Docker Model Runner:
docker model run hf.co/CodeSoft/MetaDiffusion-150M-exp
| #!/usr/bin/env python3 | |
| import argparse | |
| import json | |
| import os | |
| import sys | |
| import math | |
| import torch | |
| import torch.nn as nn | |
| import torch.nn.functional as F | |
| from safetensors.torch import load_file | |
| from transformers import AutoTokenizer, AutoConfig | |
| # --------------------------------------------------------------------------- | |
| # Model definition | |
| # --------------------------------------------------------------------------- | |
| class MetaDiffusionConfig: | |
| def __init__(self, **kwargs): | |
| for k, v in kwargs.items(): | |
| setattr(self, k, v) | |
| class RMSNorm(nn.Module): | |
| def __init__(self, hidden_size, eps=1e-6): | |
| super().__init__() | |
| self.weight = nn.Parameter(torch.ones(hidden_size)) | |
| self.eps = eps | |
| def forward(self, x): | |
| var = x.pow(2).mean(-1, keepdim=True) | |
| x = x * torch.rsqrt(var + self.eps) | |
| return self.weight * x | |
| class RotaryEmbedding(nn.Module): | |
| def __init__(self, dim, max_position_embeddings=5120, base=10000.0): | |
| super().__init__() | |
| inv_freq = 1.0 / (base ** (torch.arange(0, dim, 2).float() / dim)) | |
| self.register_buffer("inv_freq", inv_freq, persistent=False) | |
| def forward(self, x, position_ids): | |
| inv_freq_expanded = self.inv_freq[None, :, None].float().expand( | |
| position_ids.shape[0], -1, 1 | |
| ) | |
| position_ids_expanded = position_ids[:, None, :].float() | |
| freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2) | |
| emb = torch.cat((freqs, freqs), dim=-1) | |
| return emb.cos().to(dtype=x.dtype), emb.sin().to(dtype=x.dtype) | |
| def rotate_half(x): | |
| x1, x2 = x.chunk(2, dim=-1) | |
| return torch.cat((-x2, x1), dim=-1) | |
| def apply_rotary_pos_emb(q, k, cos, sin): | |
| cos = cos.unsqueeze(1) | |
| sin = sin.unsqueeze(1) | |
| q_embed = (q * cos) + (rotate_half(q) * sin) | |
| k_embed = (k * cos) + (rotate_half(k) * sin) | |
| return q_embed, k_embed | |
| class TimestepEmbedding(nn.Module): | |
| def __init__(self, hidden_size): | |
| super().__init__() | |
| self.mlp = nn.Sequential( | |
| nn.Linear(hidden_size, hidden_size * 4), | |
| nn.SiLU(), | |
| nn.Linear(hidden_size * 4, hidden_size), | |
| ) | |
| def forward(self, t): | |
| half_dim = self.mlp[0].in_features // 2 | |
| emb = math.log(10000.0) / (half_dim - 1) | |
| emb = torch.exp(torch.arange(half_dim, device=t.device) * -emb) | |
| emb = t[:, None].float() * emb[None, :] | |
| emb = torch.cat([emb.sin(), emb.cos()], dim=-1) | |
| return self.mlp(emb) | |
| class TimestepResidual(nn.Module): | |
| def __init__(self, hidden_size): | |
| super().__init__() | |
| self.proj = nn.Linear(hidden_size, hidden_size) | |
| def forward(self, x, emb): | |
| return x + self.proj(emb)[:, None, :] | |
| class SelfAttention(nn.Module): | |
| def __init__(self, config): | |
| super().__init__() | |
| self.hidden_size = config.hidden_size | |
| self.num_heads = config.num_attention_heads | |
| self.num_kv_heads = config.num_key_value_heads | |
| self.head_dim = config.head_dim | |
| self.num_kv_groups = self.num_heads // self.num_kv_heads | |
| self.q_proj = nn.Linear(config.hidden_size, self.num_heads * self.head_dim, bias=False) | |
| self.k_proj = nn.Linear(config.hidden_size, self.num_kv_heads * self.head_dim, bias=False) | |
| self.v_proj = nn.Linear(config.hidden_size, self.num_kv_heads * self.head_dim, bias=False) | |
| self.o_proj = nn.Linear(self.num_heads * self.head_dim, config.hidden_size, bias=False) | |
| self.rotary_emb = RotaryEmbedding( | |
| config.head_dim, | |
| max_position_embeddings=config.max_position_embeddings, | |
| base=config.rope_theta, | |
| ) | |
| def forward(self, x, position_ids): | |
| batch, seq, _ = x.shape | |
| q = self.q_proj(x).view(batch, seq, self.num_heads, self.head_dim).transpose(1, 2) | |
| k = self.k_proj(x).view(batch, seq, self.num_kv_heads, self.head_dim).transpose(1, 2) | |
| v = self.v_proj(x).view(batch, seq, self.num_kv_heads, self.head_dim).transpose(1, 2) | |
| cos, sin = self.rotary_emb(x, position_ids) | |
| q, k = apply_rotary_pos_emb(q, k, cos, sin) | |
| if self.num_kv_groups > 1: | |
| k = k.repeat_interleave(self.num_kv_groups, dim=1) | |
| v = v.repeat_interleave(self.num_kv_groups, dim=1) | |
| out = F.scaled_dot_product_attention(q, k, v) | |
| out = out.transpose(1, 2).contiguous().view(batch, seq, -1) | |
| return self.o_proj(out) | |
| class MLP(nn.Module): | |
| def __init__(self, config): | |
| super().__init__() | |
| self.gate_proj = nn.Linear(config.hidden_size, config.intermediate_size, bias=False) | |
| self.up_proj = nn.Linear(config.hidden_size, config.intermediate_size, bias=False) | |
| self.down_proj = nn.Linear(config.intermediate_size, config.hidden_size, bias=False) | |
| def forward(self, x): | |
| return self.down_proj(F.silu(self.gate_proj(x)) * self.up_proj(x)) | |
| class TransformerBlock(nn.Module): | |
| def __init__(self, config): | |
| super().__init__() | |
| self.input_layernorm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps) | |
| self.self_attn = SelfAttention(config) | |
| self.post_attention_layernorm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps) | |
| self.mlp = MLP(config) | |
| self.timestep_residual = TimestepResidual(config.hidden_size) | |
| def forward(self, x, timestep_emb, position_ids): | |
| residual = x | |
| x = self.input_layernorm(x) | |
| x = self.self_attn(x, position_ids) | |
| x = residual + x | |
| x = self.timestep_residual(x, timestep_emb) | |
| residual = x | |
| x = self.post_attention_layernorm(x) | |
| x = self.mlp(x) | |
| x = residual + x | |
| x = self.timestep_residual(x, timestep_emb) | |
| return x | |
| class MetaDiffusionLM(nn.Module): | |
| def __init__(self, config): | |
| super().__init__() | |
| self.config = config | |
| self.mask_token_id = getattr(config, "mask_token_id", config.vocab_size) | |
| self.embed_tokens = nn.Embedding( | |
| config.mask_vocab_size, config.hidden_size, | |
| padding_idx=getattr(config, "pad_token_id", 1) | |
| ) | |
| self.timestep_emb = TimestepEmbedding(getattr(config, "timestep_emb_hidden", config.hidden_size)) | |
| self.layers = nn.ModuleList([TransformerBlock(config) for _ in range(config.num_hidden_layers)]) | |
| self.norm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps) | |
| self.lm_head = nn.Linear(config.hidden_size, config.mask_vocab_size, bias=False) | |
| def forward(self, input_ids, timesteps): | |
| batch, seq = input_ids.shape | |
| position_ids = torch.arange(seq, device=input_ids.device).unsqueeze(0).expand(batch, -1) | |
| x = self.embed_tokens(input_ids) | |
| t_emb = self.timestep_emb(timesteps) | |
| for layer in self.layers: | |
| x = layer(x, t_emb, position_ids) | |
| x = self.norm(x) | |
| logits = self.lm_head(x) | |
| return logits | |
| # --------------------------------------------------------------------------- | |
| # Generation | |
| # --------------------------------------------------------------------------- | |
| def cumulative_unmask_frac(i, N, schedule="cosine"): | |
| if schedule == "cosine": | |
| return 0.5 * (1 - math.cos(math.pi * i / N)) | |
| return i / N | |
| def generate(model, tokenizer, prompt, seq_len=256, num_steps=64, device="cuda", | |
| temperature=0.6, repetition_penalty=1.5, watch=False, | |
| watch_every=1, mask_token_id=32000): | |
| model.eval() | |
| # Tokenize prompt | |
| prompt_ids = tokenizer.encode(prompt, add_special_tokens=False) | |
| prompt_ids = torch.tensor([prompt_ids], device=device) | |
| # Build input: prompt + [MASK] tokens | |
| total_len = seq_len | |
| gen_len = max(total_len - prompt_ids.shape[1], 0) | |
| input_ids = torch.full((1, total_len), mask_token_id, device=device, dtype=torch.long) | |
| input_ids[0, :prompt_ids.shape[1]] = prompt_ids | |
| for i in range(num_steps): | |
| frac_now = cumulative_unmask_frac(i, num_steps) | |
| frac_next = cumulative_unmask_frac(i + 1, num_steps) | |
| # How many tokens to unmask this step | |
| n_masked = (input_ids == mask_token_id).sum().item() | |
| n_total_to_unmask = int((frac_next - frac_now) * (total_len - prompt_ids.shape[1]) + 0.5) | |
| if i == num_steps - 1: | |
| n_unmask = n_masked | |
| else: | |
| n_unmask = max(n_total_to_unmask, 1) if n_masked > 0 else 0 | |
| t = 1.0 - frac_now | |
| t_batch = torch.full((1,), t, device=device) | |
| with torch.no_grad(): | |
| logits = model(input_ids, t_batch) | |
| # Prevent model from predicting [MASK] token | |
| logits[:, :, mask_token_id] = -1e9 | |
| if repetition_penalty != 1.0: | |
| for tok in input_ids[0].unique(): | |
| tok_idx = tok.item() | |
| logits[0, :, tok_idx] = torch.where( | |
| logits[0, :, tok_idx] < 0, | |
| logits[0, :, tok_idx] * repetition_penalty, | |
| logits[0, :, tok_idx] / repetition_penalty | |
| ) | |
| # Sample at masked positions | |
| mask_positions = (input_ids == mask_token_id) | |
| mask_logits = logits[mask_positions] | |
| probs = F.softmax(mask_logits / temperature, dim=-1) | |
| sampled = torch.multinomial(probs, 1).squeeze(-1) | |
| # Select which masks to fill (by confidence) | |
| if n_unmask < mask_positions.sum(): | |
| # Get entropy/confidence for each mask | |
| log_probs = F.log_softmax(mask_logits, dim=-1) | |
| confidence, _ = log_probs.max(dim=-1) | |
| _, top_indices = confidence.topk(n_unmask) | |
| # Only fill top-confidence positions | |
| mask_flat = mask_positions.nonzero(as_tuple=False) | |
| fill_positions = mask_flat[top_indices] | |
| for idx, tok in zip(fill_positions, sampled[top_indices]): | |
| input_ids[idx[0], idx[1]] = tok | |
| else: | |
| # Fill all remaining masks | |
| input_ids[mask_positions] = sampled | |
| if watch and i % watch_every == 0: | |
| text = tokenizer.decode(input_ids[0], skip_special_tokens=True) | |
| n_remaining = (input_ids == mask_token_id).sum().item() | |
| print(f"Step {i+1}/{num_steps} | LR={t:.3f} | Masks remaining: {n_remaining}") | |
| print(text[:200]) | |
| print() | |
| # Decode | |
| return tokenizer.decode(input_ids[0], skip_special_tokens=False) | |
| def load_model(model_path, device="cuda"): | |
| """Load model from safetensors file, directory, or HuggingFace Hub.""" | |
| # Check if it's a local path or HF hub id | |
| is_file = os.path.isfile(model_path) and model_path.endswith(".safetensors") | |
| is_dir = os.path.isdir(model_path) | |
| is_local = is_file or is_dir | |
| if is_local: | |
| if is_file: | |
| safetensors_path = model_path | |
| config_path = os.path.join(os.path.dirname(model_path), "config.json") | |
| else: | |
| config_path = os.path.join(model_path, "config.json") | |
| safetensors_path = os.path.join(model_path, "model.safetensors") | |
| if not os.path.isfile(safetensors_path): | |
| print(f"ERROR: model.safetensors not found in {model_path}") | |
| sys.exit(1) | |
| if not os.path.isfile(config_path): | |
| print(f"ERROR: config.json not found next to {safetensors_path}") | |
| sys.exit(1) | |
| with open(config_path) as f: | |
| config_dict = json.load(f) | |
| else: | |
| # Load from HuggingFace Hub | |
| from huggingface_hub import hf_hub_download | |
| config_path = hf_hub_download(model_path, "config.json") | |
| safetensors_path = hf_hub_download(model_path, "model.safetensors") | |
| with open(config_path) as f: | |
| config_dict = json.load(f) | |
| # Build config | |
| config = MetaDiffusionConfig(**config_dict) | |
| model = MetaDiffusionLM(config) | |
| model = model.to(device) | |
| # Load weights (remap HF names to model names) | |
| state_dict = load_file(safetensors_path) | |
| # Remap from HF naming to model naming | |
| new_state_dict = {} | |
| for key, value in state_dict.items(): | |
| if key.startswith("model."): | |
| new_key = key[len("model."):] | |
| else: | |
| new_key = key | |
| new_state_dict[new_key] = value | |
| result = model.load_state_dict(new_state_dict, strict=False) | |
| if result.missing_keys: | |
| print(f" Warning: missing keys: {result.missing_keys[:5]}...") | |
| if result.unexpected_keys: | |
| print(f" Warning: unexpected keys: {result.unexpected_keys[:5]}...") | |
| model = model.to(device) | |
| print(f" Model loaded: {sum(p.numel() for p in model.parameters())/1e6:.1f}M params") | |
| return model, config | |
| def main(): | |
| parser = argparse.ArgumentParser(description="MetaDiffusion inference") | |
| parser.add_argument("--model-path", required=True, help="Path to model directory or HF Hub ID") | |
| parser.add_argument("--prompt", default="The cat sat on the", help="Input prompt") | |
| parser.add_argument("--seq-len", type=int, default=256, help="Sequence length") | |
| parser.add_argument("--num-steps", type=int, default=512, help="Denoising steps") | |
| parser.add_argument("--temperature", type=float, default=0.6, help="Sampling temperature") | |
| parser.add_argument("--repetition-penalty", type=float, default=1.5, help="Repetition penalty") | |
| parser.add_argument("--device", default="cuda", help="Device (cuda/cpu)") | |
| parser.add_argument("--watch", action="store_true", help="Show denoising progress") | |
| parser.add_argument("--watch-every", type=int, default=4, help="Show progress every N steps") | |
| parser.add_argument("--base-model", default="SupraLabs/Supra-1.5-50M-Base-exp", | |
| help="HuggingFace model for tokenizer") | |
| args = parser.parse_args() | |
| if "cpu" in args.device: | |
| device = torch.device("cpu") | |
| else: | |
| device = torch.device(args.device if torch.cuda.is_available() else "cpu") | |
| model, config = load_model(args.model_path, device) | |
| # Load tokenizer from base model | |
| tokenizer = AutoTokenizer.from_pretrained(args.base_model) | |
| mask_token_id = getattr(config, "mask_token_id", config.vocab_size) | |
| print(f"\nPrompt: '{args.prompt}'") | |
| print(f"Steps: {args.num_steps} | Temp: {args.temperature}") | |
| print() | |
| output = generate( | |
| model, tokenizer, args.prompt, | |
| seq_len=args.seq_len, num_steps=args.num_steps, | |
| device=device, temperature=args.temperature, | |
| repetition_penalty=args.repetition_penalty, | |
| watch=args.watch, | |
| watch_every=args.watch_every, mask_token_id=mask_token_id | |
| ) | |
| print("Output:") | |
| print(output) | |
| if __name__ == "__main__": | |
| main() | |