Text Generation
Transformers
Safetensors
Mongolian
rdt
traditional-mongolian
recurrent-depth-transformer
mamba
causal-lm
custom-code
custom_code
Instructions to use Montlok/DoL-1.2-Base with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Montlok/DoL-1.2-Base with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="Montlok/DoL-1.2-Base", trust_remote_code=True)# pip install -U transformers accelerate # Load model directly from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("Montlok/DoL-1.2-Base", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use Montlok/DoL-1.2-Base with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "Montlok/DoL-1.2-Base" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Montlok/DoL-1.2-Base", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/Montlok/DoL-1.2-Base
- SGLang
How to use Montlok/DoL-1.2-Base 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 "Montlok/DoL-1.2-Base" \ --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": "Montlok/DoL-1.2-Base", "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 "Montlok/DoL-1.2-Base" \ --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": "Montlok/DoL-1.2-Base", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use Montlok/DoL-1.2-Base with Docker Model Runner:
docker model run hf.co/Montlok/DoL-1.2-Base
Download Model/blocks.py from Montlok/DoL-1.2-Base: direct link, hf CLI and curl.
- Browser
- Download file 7.51 kB
-
https://huggingface.co/Montlok/DoL-1.2-Base/resolve/main/Model/blocks.py
- Command line
-
hf download hf://Montlok/DoL-1.2-Base/Model/blocks.py
-
curl -L -o blocks.py https://huggingface.co/Montlok/DoL-1.2-Base/resolve/main/Model/blocks.py
7.51 kB
| # -*- coding: utf-8 -*- | |
| from __future__ import annotations | |
| import torch | |
| import torch.nn as nn | |
| from Model.layers.mla import MLA | |
| from Model.layers.mamba3_layer import Mamba3Layer | |
| from Model.layers.mixture_lora_ffn import MixtureLoRAFFN | |
| from Model.layers.rmsnorm import RMSNorm | |
| from Model.layers.swiglu import SwiGLU | |
| def _build_ffn(cfg): | |
| """Recurrent-block FFN: step-aware Mixture-of-LoRAs when ``use_mol``, else the | |
| plain shared SwiGLU. Prelude/coda (``StandardBlock``) always use plain SwiGLU | |
| -- they are non-recurrent, so step-aware expert routing has no step to | |
| condition on.""" | |
| if getattr(cfg, "use_mol", False): | |
| return MixtureLoRAFFN( | |
| cfg.d_model, | |
| cfg.ffn_hidden, | |
| cfg.mol_experts, | |
| cfg.mol_rank, | |
| cfg.recurrence_step_table, | |
| step_aware=cfg.mol_step_aware, | |
| router_temp=cfg.mol_router_temp, | |
| top_k=cfg.mol_top_k, | |
| init_std=cfg.init_std, | |
| rmsnorm_eps=cfg.rmsnorm_eps, | |
| ) | |
| return SwiGLU(cfg.d_model, cfg.ffn_hidden) | |
| def _apply_ffn(ffn, x, step): | |
| """Forward a ``_build_ffn`` FFN, threading the recurrent step index only into | |
| a MixtureLoRAFFN (plain SwiGLU has no ``step`` kwarg and ignores it).""" | |
| if isinstance(ffn, MixtureLoRAFFN): | |
| return ffn(x, step=step) | |
| return ffn(x) | |
| class StandardBlock(nn.Module): | |
| def __init__(self, cfg, layer_idx: int | None = None): | |
| super().__init__() | |
| self.layer_idx = layer_idx | |
| self.attn_norm = RMSNorm(cfg.d_model, eps=cfg.rmsnorm_eps) | |
| self.attn = MLA(cfg) | |
| self.ffn_norm = RMSNorm(cfg.d_model, eps=cfg.rmsnorm_eps) | |
| self.ffn = SwiGLU(cfg.d_model, cfg.ffn_hidden) | |
| def forward( | |
| self, | |
| x: torch.Tensor, | |
| word_pos: torch.Tensor | None = None, | |
| morph_depth: torch.Tensor | None = None, | |
| attn_mask: torch.Tensor | None = None, | |
| causal: bool = True, | |
| cache=None, | |
| pos_offset: int = 0, | |
| ) -> torch.Tensor: | |
| x = x + self.attn( | |
| self.attn_norm(x), | |
| word_pos=word_pos, | |
| morph_depth=morph_depth, | |
| attn_mask=attn_mask, | |
| causal=causal, | |
| cache=cache, | |
| pos_offset=pos_offset, | |
| ) | |
| x = x + self.ffn(self.ffn_norm(x)) | |
| return x | |
| class AttnSubLayer(nn.Module): | |
| def __init__(self, cfg, layer_idx: int | None = None): | |
| super().__init__() | |
| self.layer_idx = layer_idx | |
| self.attn_norm = RMSNorm(cfg.d_model, eps=cfg.rmsnorm_eps) | |
| self.attn = MLA(cfg) | |
| self.ffn_norm = RMSNorm(cfg.d_model, eps=cfg.rmsnorm_eps) | |
| self.ffn = _build_ffn(cfg) | |
| def forward( | |
| self, | |
| x: torch.Tensor, | |
| word_pos: torch.Tensor | None = None, | |
| morph_depth: torch.Tensor | None = None, | |
| attn_mask: torch.Tensor | None = None, | |
| causal: bool = True, | |
| cache=None, | |
| pos_offset: int = 0, | |
| step: int | None = None, | |
| ) -> torch.Tensor: | |
| x = x + self.attn( | |
| self.attn_norm(x), | |
| word_pos=word_pos, | |
| morph_depth=morph_depth, | |
| attn_mask=attn_mask, | |
| causal=causal, | |
| cache=cache, | |
| pos_offset=pos_offset, | |
| ) | |
| x = x + _apply_ffn(self.ffn, self.ffn_norm(x), step) | |
| return x | |
| class MambaSubLayer(nn.Module): | |
| def __init__(self, cfg, layer_idx: int | None = None): | |
| super().__init__() | |
| self.layer_idx = layer_idx | |
| self.mamba = Mamba3Layer(cfg, layer_idx=layer_idx) | |
| self.ffn_norm = RMSNorm(cfg.d_model, eps=cfg.rmsnorm_eps) | |
| self.ffn = _build_ffn(cfg) | |
| def forward( | |
| self, | |
| x: torch.Tensor, | |
| attn_mask: torch.Tensor | None = None, | |
| cache=None, | |
| step: int | None = None, | |
| **kwargs, | |
| ) -> torch.Tensor: | |
| x = self.mamba(x, attn_mask=attn_mask, cache=cache) | |
| x = x + _apply_ffn(self.ffn, self.ffn_norm(x), step) | |
| if attn_mask is not None: | |
| x = x * attn_mask.to(device=x.device, dtype=x.dtype).unsqueeze(-1) | |
| return x | |
| class RecurrentBlock(nn.Module): | |
| def __init__(self, cfg): | |
| super().__init__() | |
| self.cfg = cfg | |
| self.layer_types = self._interleave( | |
| cfg.mamba_per_block, | |
| cfg.attn_per_block, | |
| ) | |
| self.layers = nn.ModuleList( | |
| self._make_layer(cfg, kind, idx) | |
| for idx, kind in enumerate(self.layer_types) | |
| ) | |
| def _interleave(n_mamba: int, n_attn: int) -> list[str]: | |
| if n_mamba < 0 or n_attn < 0: | |
| raise ValueError("layer counts must be non-negative") | |
| total = n_mamba + n_attn | |
| if total <= 0: | |
| raise ValueError("recurrent block cannot be empty") | |
| if n_attn == 0: | |
| return ["mamba"] * n_mamba | |
| if n_mamba == 0: | |
| return ["attn"] * n_attn | |
| result: list[str] = [] | |
| m_used = 0 | |
| a_used = 0 | |
| for pos in range(total): | |
| target_attn = round((pos + 1) * n_attn / total) | |
| if a_used < target_attn and a_used < n_attn: | |
| result.append("attn") | |
| a_used += 1 | |
| elif m_used < n_mamba: | |
| result.append("mamba") | |
| m_used += 1 | |
| else: | |
| result.append("attn") | |
| a_used += 1 | |
| return result | |
| def _make_layer(cfg, kind: str, layer_idx: int) -> nn.Module: | |
| if kind == "mamba": | |
| return MambaSubLayer(cfg, layer_idx=layer_idx) | |
| if kind == "attn": | |
| return AttnSubLayer(cfg, layer_idx=layer_idx) | |
| raise ValueError(f"unknown layer type: {kind}") | |
| def forward( | |
| self, | |
| x: torch.Tensor, | |
| word_pos: torch.Tensor | None = None, | |
| morph_depth: torch.Tensor | None = None, | |
| attn_mask: torch.Tensor | None = None, | |
| causal: bool = True, | |
| step: int | None = None, | |
| ) -> torch.Tensor: | |
| for layer in self.layers: | |
| x = layer( | |
| x, | |
| word_pos=word_pos, | |
| morph_depth=morph_depth, | |
| attn_mask=attn_mask, | |
| causal=causal, | |
| step=step, | |
| ) | |
| return x | |
| def _check() -> None: | |
| from Model.config import tiny_config | |
| torch.manual_seed(0) | |
| cfg = tiny_config() | |
| bsz, seq_len = 2, 16 | |
| x = torch.randn(bsz, seq_len, cfg.d_model) | |
| word_pos = torch.arange(seq_len).unsqueeze(0).expand(bsz, seq_len) | |
| morph_depth = torch.zeros(bsz, seq_len, dtype=torch.long) | |
| block = StandardBlock(cfg) | |
| y = block( | |
| x, | |
| word_pos=word_pos, | |
| morph_depth=morph_depth, | |
| ) | |
| print("StandardBlock") | |
| print(f" shape: {tuple(x.shape)} -> {tuple(y.shape)}") | |
| recurrent = RecurrentBlock(cfg) | |
| y2 = recurrent( | |
| x, | |
| word_pos=word_pos, | |
| morph_depth=morph_depth, | |
| ) | |
| print("RecurrentBlock") | |
| print(f" layer_types: {recurrent.layer_types}") | |
| print(f" shape: {tuple(x.shape)} -> {tuple(y2.shape)}") | |
| print(f" params: {sum(p.numel() for p in recurrent.parameters()):,}") | |
| x2 = torch.randn(bsz, seq_len, cfg.d_model, requires_grad=True) | |
| loss = recurrent( | |
| x2, | |
| word_pos=word_pos, | |
| morph_depth=morph_depth, | |
| ).sum() | |
| loss.backward() | |
| print(f" grad_norm: {x2.grad.norm().item():.6f}") | |
| if __name__ == "__main__": | |
| _check() | |