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 Tokenizer/multimodal/processor.py from Montlok/DoL-1.2-Base: direct link, hf CLI and curl.
- Browser
- Download file 12.2 kB
-
https://huggingface.co/Montlok/DoL-1.2-Base/resolve/main/Tokenizer/multimodal/processor.py
- Command line
-
hf download hf://Montlok/DoL-1.2-Base/Tokenizer/multimodal/processor.py
-
curl -L -o processor.py https://huggingface.co/Montlok/DoL-1.2-Base/resolve/main/Tokenizer/multimodal/processor.py
12.2 kB
| # -*- coding: utf-8 -*- | |
| """Multimodal tokenizer processor.""" | |
| from __future__ import annotations | |
| from dataclasses import dataclass, field | |
| from typing import Any | |
| from Tokenizer.unified.encoded import EncodedToken | |
| from .image_placeholders import ( | |
| image_patch_count, | |
| image_placeholder_tokens, | |
| ) | |
| from .video_placeholders import ( | |
| video_patch_count, | |
| video_placeholder_tokens, | |
| ) | |
| from .tokens import IMAGE_PLACEHOLDER, VIDEO_PLACEHOLDER | |
| class MultimodalEncoding: | |
| input_ids: list[int] | |
| attention_mask: list[int] | |
| tokens: list[EncodedToken] | |
| image_token_spans: list[tuple[int, int]] | |
| video_token_spans: list[tuple[int, int]] = field(default_factory=list) | |
| images: list[Any] = field(default_factory=list) | |
| videos: list[Any] = field(default_factory=list) | |
| pixel_values: Any = None | |
| class _PlaceholderRecord: | |
| start: int | |
| end: int | |
| patch_count: int | |
| class MultimodalProcessor: | |
| def __init__( | |
| self, | |
| tokenizer, | |
| image_processor=None, | |
| patch_size: int = 14, | |
| merge_size: int = 2, | |
| temporal_patch_size: int = 2, | |
| ): | |
| self.tokenizer = tokenizer | |
| self.image_processor = image_processor | |
| self.patch_size = patch_size | |
| self.merge_size = merge_size | |
| self.temporal_patch_size = temporal_patch_size | |
| def __call__( | |
| self, | |
| text: str, | |
| images: list[Any] | None = None, | |
| image_sizes: list[Any] | None = None, | |
| videos: list[Any] | None = None, | |
| video_sizes: list[Any] | None = None, | |
| add_bos: bool = False, | |
| add_eos: bool = False, | |
| ) -> MultimodalEncoding: | |
| image_list = list(images or []) | |
| sizes = list(image_sizes or []) | |
| video_list = list(videos or []) | |
| vsizes = list(video_sizes or []) | |
| n_img_holes = text.count(IMAGE_PLACEHOLDER) | |
| n_vid_holes = text.count(VIDEO_PLACEHOLDER) | |
| if len(image_list) != n_img_holes: | |
| raise ValueError( | |
| f"<image> placeholder count ({n_img_holes}) does not match " | |
| f"images length ({len(image_list)})" | |
| ) | |
| if len(video_list) != n_vid_holes: | |
| raise ValueError( | |
| f"<video> placeholder count ({n_vid_holes}) does not match " | |
| f"videos length ({len(video_list)})" | |
| ) | |
| if sizes and len(sizes) != n_img_holes: | |
| raise ValueError( | |
| f"<image> placeholder count ({n_img_holes}) does not match " | |
| f"image_sizes length ({len(sizes)})" | |
| ) | |
| if vsizes and len(vsizes) != n_vid_holes: | |
| raise ValueError( | |
| f"<video> placeholder count ({n_vid_holes}) does not match " | |
| f"video_sizes length ({len(vsizes)})" | |
| ) | |
| # Default sizes for missing entries: assume single-patch image/video. | |
| if not sizes and n_img_holes: | |
| sizes = [None] * n_img_holes | |
| if not vsizes and n_vid_holes: | |
| vsizes = [None] * n_vid_holes | |
| expanded, image_records, video_records, boundary_map = self._expand_placeholders( | |
| text, sizes, vsizes | |
| ) | |
| result = self.tokenizer.encode_with_spans( | |
| expanded, add_bos=add_bos, add_eos=add_eos | |
| ) | |
| tokens = self._annotate_patches( | |
| result.tokens, image_records, video_records, boundary_map | |
| ) | |
| img_spans = self._collect_spans( | |
| tokens, "<image_start>", "<image_patch>", "<image_end>", image_records | |
| ) | |
| vid_spans = self._collect_spans( | |
| tokens, "<video_start>", "<video_patch>", "<video_end>", video_records | |
| ) | |
| # Invariant: attention_mask aligns with input_ids | |
| assert len(result.attention_mask) == len(result.input_ids) | |
| processed_images = image_list | |
| if self.image_processor is not None and image_list: | |
| processed_images = self.image_processor(image_list) | |
| return MultimodalEncoding( | |
| input_ids=result.input_ids, | |
| attention_mask=result.attention_mask, | |
| tokens=tokens, | |
| image_token_spans=img_spans, | |
| video_token_spans=vid_spans, | |
| images=processed_images, | |
| videos=video_list, | |
| ) | |
| # ---- expansion ---- | |
| def _expand_placeholders( | |
| self, text: str, image_sizes: list[Any], video_sizes: list[Any] | |
| ) -> tuple[str, list[_PlaceholderRecord], list[_PlaceholderRecord], list[int]]: | |
| out: list[str] = [] | |
| boundary_map = [0] | |
| image_records: list[_PlaceholderRecord] = [] | |
| video_records: list[_PlaceholderRecord] = [] | |
| img_idx = 0 | |
| vid_idx = 0 | |
| i = 0 | |
| while i < len(text): | |
| if text.startswith(IMAGE_PLACEHOLDER, i): | |
| n = self._patches_image(image_sizes[img_idx]) | |
| end = i + len(IMAGE_PLACEHOLDER) | |
| image_records.append(_PlaceholderRecord(i, end, n)) | |
| expanded = "".join(image_placeholder_tokens(n)) | |
| out.append(expanded) | |
| boundary_map.extend([end] * len(expanded)) | |
| img_idx += 1 | |
| i = end | |
| continue | |
| if text.startswith(VIDEO_PLACEHOLDER, i): | |
| n = self._patches_video(video_sizes[vid_idx]) | |
| end = i + len(VIDEO_PLACEHOLDER) | |
| video_records.append(_PlaceholderRecord(i, end, n)) | |
| expanded = "".join(video_placeholder_tokens(n)) | |
| out.append(expanded) | |
| boundary_map.extend([end] * len(expanded)) | |
| vid_idx += 1 | |
| i = end | |
| continue | |
| out.append(text[i]) | |
| boundary_map.append(i + 1) | |
| i += 1 | |
| return "".join(out), image_records, video_records, boundary_map | |
| def _expand_images(self, text: str, sizes: list[Any]) -> str: | |
| parts = text.split(IMAGE_PLACEHOLDER) | |
| if len(parts) == 1: | |
| return text | |
| out = [parts[0]] | |
| for i, size in enumerate(sizes): | |
| n = self._patches_image(size) | |
| out.append("".join(image_placeholder_tokens(n))) | |
| out.append(parts[i + 1]) | |
| return "".join(out) | |
| def _expand_videos(self, text: str, sizes: list[Any]) -> str: | |
| parts = text.split(VIDEO_PLACEHOLDER) | |
| if len(parts) == 1: | |
| return text | |
| out = [parts[0]] | |
| for i, size in enumerate(sizes): | |
| n = self._patches_video(size) | |
| out.append("".join(video_placeholder_tokens(n))) | |
| out.append(parts[i + 1]) | |
| return "".join(out) | |
| def _patches_image(self, size: Any) -> int: | |
| if size is None: | |
| return 1 | |
| if isinstance(size, dict): | |
| w = int(size.get("width") or size.get("w")) | |
| h = int(size.get("height") or size.get("h")) | |
| else: | |
| w, h = int(size[0]), int(size[1]) | |
| return image_patch_count(w, h, self.patch_size, self.merge_size) | |
| def _patches_video(self, size: Any) -> int: | |
| if size is None: | |
| return 1 | |
| if isinstance(size, dict): | |
| f = int(size.get("frames") or size.get("num_frames")) | |
| w = int(size.get("width") or size.get("w")) | |
| h = int(size.get("height") or size.get("h")) | |
| else: | |
| f, w, h = int(size[0]), int(size[1]), int(size[2]) | |
| return video_patch_count( | |
| f, w, h, self.patch_size, self.temporal_patch_size, self.merge_size | |
| ) | |
| # ---- annotation & spans ---- | |
| def _annotate_patches( | |
| self, | |
| tokens: list[EncodedToken], | |
| image_records: list[_PlaceholderRecord], | |
| video_records: list[_PlaceholderRecord], | |
| boundary_map: list[int], | |
| ) -> list[EncodedToken]: | |
| """Attach image_index/video_index metadata to patch tokens.""" | |
| out: list[EncodedToken] = [] | |
| img_idx = -1 | |
| vid_idx = -1 | |
| in_img = False | |
| in_vid = False | |
| for t in tokens: | |
| meta = t.metadata | |
| start, end = self._remap_offsets(t.start, t.end, boundary_map) | |
| if t.token == "<image_start>": | |
| img_idx += 1 | |
| in_img = True | |
| meta = self._placeholder_metadata(meta, image_records, img_idx, "image_index") | |
| elif t.token == "<image_end>": | |
| meta = self._placeholder_metadata(meta, image_records, img_idx, "image_index") | |
| in_img = False | |
| elif t.token == "<image_patch>" and in_img: | |
| meta = self._placeholder_metadata(meta, image_records, img_idx, "image_index") | |
| elif t.token == "<video_start>": | |
| vid_idx += 1 | |
| in_vid = True | |
| meta = self._placeholder_metadata(meta, video_records, vid_idx, "video_index") | |
| elif t.token == "<video_end>": | |
| meta = self._placeholder_metadata(meta, video_records, vid_idx, "video_index") | |
| in_vid = False | |
| elif t.token == "<video_patch>" and in_vid: | |
| meta = self._placeholder_metadata(meta, video_records, vid_idx, "video_index") | |
| if meta is not t.metadata: | |
| source_span = meta.get("source_span") if meta else None | |
| if source_span is not None: | |
| start, end = int(source_span[0]), int(source_span[1]) | |
| out.append( | |
| EncodedToken( | |
| t.id, t.token, t.track, start, end, t.surface, meta | |
| ) | |
| ) | |
| elif start != t.start or end != t.end: | |
| out.append( | |
| EncodedToken( | |
| t.id, t.token, t.track, start, end, t.surface, t.metadata | |
| ) | |
| ) | |
| else: | |
| out.append(t) | |
| return out | |
| def _remap_offsets( | |
| self, start: int, end: int, boundary_map: list[int] | |
| ) -> tuple[int, int]: | |
| if start == -1 and end == -1: | |
| return start, end | |
| if not boundary_map: | |
| return start, end | |
| start_idx = min(max(start, 0), len(boundary_map) - 1) | |
| end_idx = min(max(end, 0), len(boundary_map) - 1) | |
| return boundary_map[start_idx], boundary_map[end_idx] | |
| def _placeholder_metadata( | |
| self, | |
| meta: dict | None, | |
| records: list[_PlaceholderRecord], | |
| index: int, | |
| index_key: str, | |
| ) -> dict: | |
| merged = {**(meta or {}), index_key: index} | |
| if 0 <= index < len(records): | |
| record = records[index] | |
| merged["source_span"] = [record.start, record.end] | |
| return merged | |
| def _collect_spans( | |
| self, | |
| tokens: list[EncodedToken], | |
| start_tok: str, | |
| patch_tok: str, | |
| end_tok: str, | |
| records: list[_PlaceholderRecord], | |
| ) -> list[tuple[int, int]]: | |
| spans: list[tuple[int, int]] = [] | |
| start: int | None = None | |
| for idx, t in enumerate(tokens): | |
| if t.token == start_tok: | |
| start = idx | |
| elif t.token == end_tok and start is not None: | |
| spans.append((start, idx + 1)) | |
| start = None | |
| if len(spans) != len(records): | |
| raise ValueError( | |
| f"{start_tok}/{end_tok} span count ({len(spans)}) does not match " | |
| f"placeholder count ({len(records)})" | |
| ) | |
| for i, (span_start, span_end) in enumerate(spans): | |
| patch_count = sum(1 for token in tokens[span_start:span_end] if token.token == patch_tok) | |
| if patch_count != records[i].patch_count: | |
| raise ValueError( | |
| f"{patch_tok} count in span {i} is {patch_count}, " | |
| f"expected {records[i].patch_count}" | |
| ) | |
| if span_end - span_start != records[i].patch_count + 2: | |
| raise ValueError( | |
| f"{start_tok}/{end_tok} span length for placeholder {i} is " | |
| f"{span_end - span_start}, expected {records[i].patch_count + 2}" | |
| ) | |
| return spans | |