Text Generation
Transformers
Safetensors
phi3
dashq
quantized
post-training-quantization
int2
conversational
custom_code
text-generation-inference
Instructions to use jkim96/phi-4-DASHQ-INT2-g32 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use jkim96/phi-4-DASHQ-INT2-g32 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="jkim96/phi-4-DASHQ-INT2-g32", trust_remote_code=True) messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("jkim96/phi-4-DASHQ-INT2-g32", trust_remote_code=True) model = AutoModelForCausalLM.from_pretrained("jkim96/phi-4-DASHQ-INT2-g32", 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=40) print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use jkim96/phi-4-DASHQ-INT2-g32 with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "jkim96/phi-4-DASHQ-INT2-g32" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "jkim96/phi-4-DASHQ-INT2-g32", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/jkim96/phi-4-DASHQ-INT2-g32
- SGLang
How to use jkim96/phi-4-DASHQ-INT2-g32 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 "jkim96/phi-4-DASHQ-INT2-g32" \ --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": "jkim96/phi-4-DASHQ-INT2-g32", "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 "jkim96/phi-4-DASHQ-INT2-g32" \ --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": "jkim96/phi-4-DASHQ-INT2-g32", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use jkim96/phi-4-DASHQ-INT2-g32 with Docker Model Runner:
docker model run hf.co/jkim96/phi-4-DASHQ-INT2-g32
| """Inference code for this DASH-Q checkpoint. | |
| Generated by export_hf_repo.py -- do not edit by hand. | |
| Weights are group-wise asymmetric integers packed into int32 words; the layout of | |
| each quantized layer is described by `dashq_config.json`. At load time the layers | |
| are converted to the format used by the Triton kernels in `dashq_kernel.py`, with | |
| a PyTorch dequantize-and-matmul fallback when Triton is unavailable. | |
| """ | |
| from __future__ import annotations | |
| import json | |
| import os | |
| from typing import Any, Dict, Optional | |
| import torch | |
| import torch.nn as nn | |
| import torch.nn.functional as F | |
| from transformers import AutoConfig, Phi3ForCausalLM | |
| try: | |
| from .dashq_kernel import TRITON_AVAILABLE, SUPPORTED_NBITS, TritonQuantLinear | |
| except ImportError: # loaded as a flat module by trust_remote_code | |
| from dashq_kernel import TRITON_AVAILABLE, SUPPORTED_NBITS, TritonQuantLinear | |
| DASHQ_CONFIG_FILE = "dashq_config.json" | |
| def _unpack_int_values(packed: torch.Tensor, nbits: int, numel: int) -> torch.Tensor: | |
| values_per_word = max(1, 32 // nbits) | |
| mask = (1 << nbits) - 1 | |
| shifts = torch.arange(values_per_word, device=packed.device, dtype=torch.int32) * nbits | |
| out = (packed.view(-1, 1) >> shifts.view(1, -1)) & mask | |
| return out.reshape(-1)[:numel] | |
| class DashQPackedLinear(nn.Module): | |
| """Checkpoint buffers for one quantized layer.""" | |
| def __init__(self, in_features: int, out_features: int, nbits: int, group_size: int, | |
| bias: bool, dtype: torch.dtype, quant_in_features: Optional[int] = None) -> None: | |
| super().__init__() | |
| self.in_features = int(in_features) | |
| self.quant_in_features = int(quant_in_features or in_features) | |
| self.out_features = int(out_features) | |
| self.nbits = int(nbits) | |
| self.group_size = int(group_size) | |
| self.linear_dtype = dtype | |
| self.numel = self.out_features * self.quant_in_features | |
| self.num_groups = self.numel // self.group_size | |
| values_per_word = max(1, 32 // self.nbits) | |
| n_words = (self.numel + values_per_word - 1) // values_per_word | |
| self.register_buffer("W_q_packed", torch.zeros(n_words, dtype=torch.int32)) | |
| self.register_buffer("scale", torch.zeros(self.num_groups, 1, dtype=torch.float16)) | |
| self.register_buffer("zero", torch.zeros(self.num_groups, 1, dtype=torch.float16)) | |
| if bias: | |
| self.bias = nn.Parameter(torch.zeros(self.out_features, dtype=dtype), requires_grad=False) | |
| else: | |
| self.register_parameter("bias", None) | |
| self.kernel: Optional[nn.Module] = None | |
| def dequantize_weight(self, dtype: torch.dtype) -> torch.Tensor: | |
| W_int = _unpack_int_values(self.W_q_packed, self.nbits, self.numel) | |
| W_int = W_int.view(self.num_groups, self.group_size).to(dtype) | |
| W = (W_int - self.zero.to(dtype)) * self.scale.to(dtype) | |
| return W.view(self.out_features, self.quant_in_features) | |
| def build_kernel(self) -> bool: | |
| if self.kernel is not None: | |
| return True | |
| if not TRITON_AVAILABLE or self.nbits not in SUPPORTED_NBITS: | |
| return False | |
| if self.quant_in_features % self.group_size or self.group_size % 2: | |
| return False | |
| if self.W_q_packed is None or not self.W_q_packed.is_cuda: | |
| return False | |
| W_int = _unpack_int_values(self.W_q_packed, self.nbits, self.numel) | |
| W_int = W_int.view(self.out_features, self.quant_in_features) | |
| ng = self.quant_in_features // self.group_size | |
| self.kernel = TritonQuantLinear( | |
| W_int, | |
| self.scale.view(self.out_features, ng), | |
| self.zero.view(self.out_features, ng), | |
| self.nbits, | |
| self.group_size, | |
| bias=self.bias.data if self.bias is not None else None, | |
| out_dtype=self.linear_dtype, | |
| ) | |
| del W_int | |
| self._buffers["W_q_packed"] = None | |
| self._buffers["scale"] = None | |
| self._buffers["zero"] = None | |
| return True | |
| def forward(self, x: torch.Tensor) -> torch.Tensor: | |
| if self.kernel is not None: | |
| return self.kernel(x) | |
| weight = self.dequantize_weight(x.dtype) | |
| bias = self.bias.to(x.dtype) if self.bias is not None else None | |
| return F.linear(x, weight, bias) | |
| def extra_repr(self) -> str: | |
| return (f"in_features={self.in_features}, out_features={self.out_features}, " | |
| f"nbits={self.nbits}, group_size={self.group_size}") | |
| def _set_module(root: nn.Module, name: str, new_module: nn.Module) -> None: | |
| parts = name.split(".") | |
| parent = root | |
| for part in parts[:-1]: | |
| parent = getattr(parent, part) | |
| setattr(parent, parts[-1], new_module) | |
| def _get_module(root: nn.Module, name: str) -> Optional[nn.Module]: | |
| obj = root | |
| for part in name.split("."): | |
| if not hasattr(obj, part): | |
| return None | |
| obj = getattr(obj, part) | |
| return obj | |
| _DTYPES = {"float16": torch.float16, "bfloat16": torch.bfloat16, "float32": torch.float32} | |
| def _load_dashq_spec(model_id_or_path, **kwargs) -> Dict[str, Any]: | |
| """Read dashq_config.json from a local dir or the Hub.""" | |
| path = None | |
| if model_id_or_path is not None: | |
| local = os.path.join(str(model_id_or_path), DASHQ_CONFIG_FILE) | |
| if os.path.isfile(local): | |
| path = local | |
| if path is None and model_id_or_path is not None: | |
| try: | |
| from huggingface_hub import hf_hub_download | |
| path = hf_hub_download( | |
| repo_id=str(model_id_or_path), | |
| filename=DASHQ_CONFIG_FILE, | |
| revision=kwargs.get("revision"), | |
| token=kwargs.get("token"), | |
| cache_dir=kwargs.get("cache_dir"), | |
| ) | |
| except Exception: | |
| return {} | |
| if path is None: | |
| return {} | |
| with open(path, encoding="utf-8") as f: | |
| return json.load(f) | |
| def _swap_quantized_modules(model: nn.Module, modules: Dict[str, Any]) -> int: | |
| count = 0 | |
| for name, meta in modules.items(): | |
| target = _get_module(model, name) | |
| if target is None or isinstance(target, DashQPackedLinear): | |
| continue | |
| module = DashQPackedLinear( | |
| in_features=meta["in_features"], | |
| out_features=meta["out_features"], | |
| nbits=meta["nbits"], | |
| group_size=meta["group_size"], | |
| bias=getattr(target, "bias", None) is not None, | |
| dtype=_DTYPES.get(meta.get("linear_dtype", "float16"), torch.float16), | |
| quant_in_features=meta.get("quant_in_features"), | |
| ) | |
| _set_module(model, name, module) | |
| count += 1 | |
| return count | |
| class DashQPhi3ForCausalLM(Phi3ForCausalLM): | |
| """Phi3ForCausalLM whose linear layers hold DASH-Q packed quantized weights.""" | |
| def __init__(self, config): | |
| super().__init__(config) | |
| modules = (getattr(config, "dashq_modules", None) or {}) | |
| if modules: | |
| _swap_quantized_modules(self, modules) | |
| def from_pretrained(cls, pretrained_model_name_or_path=None, *args, **kwargs): | |
| config = kwargs.pop("config", None) | |
| if config is None and pretrained_model_name_or_path is not None: | |
| config = AutoConfig.from_pretrained( | |
| pretrained_model_name_or_path, | |
| trust_remote_code=True, | |
| revision=kwargs.get("revision"), | |
| token=kwargs.get("token"), | |
| cache_dir=kwargs.get("cache_dir"), | |
| ) | |
| if config is not None and not getattr(config, "dashq_modules", None): | |
| spec = _load_dashq_spec(pretrained_model_name_or_path, **kwargs) | |
| config.dashq_modules = spec.get("quantized_modules", {}) | |
| model = super().from_pretrained(pretrained_model_name_or_path, *args, config=config, **kwargs) | |
| model.build_dashq_kernels() | |
| return model | |
| def build_dashq_kernels(self, verbose: bool = True) -> "DashQPhi3ForCausalLM": | |
| """Move the packed buffers to the Triton kernel layout (no-op off CUDA).""" | |
| total = built = 0 | |
| for module in self.modules(): | |
| if isinstance(module, DashQPackedLinear): | |
| total += 1 | |
| built += int(module.build_kernel()) | |
| if verbose and total: | |
| if built: | |
| print(f">> DASH-Q: {built}/{total} linear layers using the Triton decode kernel.") | |
| else: | |
| print(f">> DASH-Q: {total} quantized layers using the PyTorch fallback path.") | |
| return self | |
| def save_pretrained(self, *args, **kwargs): | |
| released = any( | |
| isinstance(m, DashQPackedLinear) and m.kernel is not None for m in self.modules() | |
| ) | |
| if released: | |
| raise RuntimeError( | |
| "This model has been converted to the DASH-Q Triton kernel, so the packed " | |
| "buffers are no longer materialized and saving would produce an incomplete " | |
| "checkpoint. Reload with build_dashq_kernels() skipped if you need to re-save." | |
| ) | |
| return super().save_pretrained(*args, **kwargs) | |