Upload Qyrou-1 EXP Base model and resumable training state
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- cache.py +98 -0
- chat_template.jinja +10 -0
- config.json +45 -0
- configuration_qyrou_arch.py +79 -0
- generation_config.json +10 -0
- marker_manifest.json +1190 -0
- model.safetensors +3 -0
- modeling_qyrou_arch.py +504 -0
- resume/artifacts/autotune.json +229 -0
- resume/artifacts/tokenizer/chat_template.jinja +10 -0
- resume/artifacts/tokenizer/marker_manifest.json +1190 -0
- resume/artifacts/tokenizer/special_tokens_map.json +158 -0
- resume/artifacts/tokenizer/tokenizer.json +0 -0
- resume/artifacts/tokenizer/tokenizer_config.json +10 -0
- resume/artifacts/tokenizer/tokenizer_quality.json +16 -0
- resume/checkpoints/qyrou-1-exp-base/checkpoint-step-000680000/manifest.json +49 -0
- resume/checkpoints/qyrou-1-exp-base/checkpoint-step-000680000/model/cache.py +98 -0
- resume/checkpoints/qyrou-1-exp-base/checkpoint-step-000680000/model/config.json +45 -0
- resume/checkpoints/qyrou-1-exp-base/checkpoint-step-000680000/model/configuration_qyrou_arch.py +79 -0
- resume/checkpoints/qyrou-1-exp-base/checkpoint-step-000680000/model/generation_config.json +10 -0
- resume/checkpoints/qyrou-1-exp-base/checkpoint-step-000680000/model/model.safetensors +3 -0
- resume/checkpoints/qyrou-1-exp-base/checkpoint-step-000680000/model/modeling_qyrou_arch.py +504 -0
- resume/checkpoints/qyrou-1-exp-base/checkpoint-step-000680000/model/triton_kernels.py +110 -0
- resume/checkpoints/qyrou-1-exp-base/checkpoint-step-000680000/training_state.pt +3 -0
- resume/checkpoints/qyrou-1-exp-base/index.json +16 -0
- resume/checkpoints/qyrou-1-exp-base/latest.json +6 -0
- resume/configs/qyrou_1_exp_base.json +86 -0
- source/QYROU_ARCH_ARCHITECTURE_AUDIT.md +212 -0
- source/TRAINING.md +44 -0
- source/attribution.md +176 -0
- source/pyproject.toml +32 -0
- source/qyrou_arch/__init__.py +6 -0
- source/qyrou_arch/cache.py +98 -0
- source/qyrou_arch/chat_template.jinja +10 -0
- source/qyrou_arch/checkpointing.py +190 -0
- source/qyrou_arch/configuration_qyrou_arch.py +79 -0
- source/qyrou_arch/data.py +214 -0
- source/qyrou_arch/io_utils.py +41 -0
- source/qyrou_arch/metrics.py +122 -0
- source/qyrou_arch/modeling_qyrou_arch.py +504 -0
- source/qyrou_arch/tokenizer_markers.py +159 -0
- source/qyrou_arch/trainer.py +509 -0
- source/qyrou_arch/triton_kernels.py +110 -0
- source/requirements-windows.lock +7 -0
- source/scripts/audit_shuffled_stream.py +80 -0
- source/scripts/autotune.py +180 -0
- source/scripts/bootstrap_windows.ps1 +68 -0
- source/scripts/fetch_preview_assets.py +48 -0
- source/scripts/generate.py +46 -0
- source/scripts/gpu_smoke.py +76 -0
cache.py
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from dataclasses import dataclass, field
|
| 4 |
+
from typing import Any
|
| 5 |
+
|
| 6 |
+
import torch
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
@dataclass
|
| 10 |
+
class QyrouArchHybridCache:
|
| 11 |
+
"""Attention K/V plus short-convolution state for incremental decoding."""
|
| 12 |
+
|
| 13 |
+
num_layers: int
|
| 14 |
+
max_cache_len: int | None = None
|
| 15 |
+
attention: list[tuple[torch.Tensor, torch.Tensor] | None] = field(init=False)
|
| 16 |
+
convolution: list[torch.Tensor | None] = field(init=False)
|
| 17 |
+
seen_tokens: int = 0
|
| 18 |
+
|
| 19 |
+
def __post_init__(self) -> None:
|
| 20 |
+
self.attention = [None] * self.num_layers
|
| 21 |
+
self.convolution = [None] * self.num_layers
|
| 22 |
+
if self.max_cache_len is not None and self.max_cache_len <= 0:
|
| 23 |
+
raise ValueError("max_cache_len must be positive")
|
| 24 |
+
|
| 25 |
+
@property
|
| 26 |
+
def is_static(self) -> bool:
|
| 27 |
+
return self.max_cache_len is not None
|
| 28 |
+
|
| 29 |
+
def get_seq_length(self, _layer_idx: int = 0) -> int:
|
| 30 |
+
return self.seen_tokens
|
| 31 |
+
|
| 32 |
+
def get_max_cache_shape(self) -> int | None:
|
| 33 |
+
return self.max_cache_len
|
| 34 |
+
|
| 35 |
+
def update_attention(
|
| 36 |
+
self,
|
| 37 |
+
layer_idx: int,
|
| 38 |
+
key: torch.Tensor,
|
| 39 |
+
value: torch.Tensor,
|
| 40 |
+
cache_position: torch.Tensor,
|
| 41 |
+
) -> tuple[torch.Tensor, torch.Tensor]:
|
| 42 |
+
if key.ndim != 4 or key.shape != value.shape:
|
| 43 |
+
raise ValueError("K/V cache tensors must have identical [batch, heads, seq, dim] shapes")
|
| 44 |
+
if self.is_static:
|
| 45 |
+
assert self.max_cache_len is not None
|
| 46 |
+
if int(cache_position.max()) >= self.max_cache_len:
|
| 47 |
+
raise ValueError("Static cache capacity exceeded")
|
| 48 |
+
existing = self.attention[layer_idx]
|
| 49 |
+
if existing is None:
|
| 50 |
+
shape = (*key.shape[:2], self.max_cache_len, key.shape[-1])
|
| 51 |
+
key_cache = torch.zeros(shape, dtype=key.dtype, device=key.device)
|
| 52 |
+
value_cache = torch.zeros(shape, dtype=value.dtype, device=value.device)
|
| 53 |
+
else:
|
| 54 |
+
key_cache, value_cache = existing
|
| 55 |
+
key_cache.index_copy_(2, cache_position, key)
|
| 56 |
+
value_cache.index_copy_(2, cache_position, value)
|
| 57 |
+
self.attention[layer_idx] = (key_cache, value_cache)
|
| 58 |
+
visible = max(self.seen_tokens, int(cache_position.max()) + 1)
|
| 59 |
+
return key_cache[:, :, :visible], value_cache[:, :, :visible]
|
| 60 |
+
existing = self.attention[layer_idx]
|
| 61 |
+
if existing is not None:
|
| 62 |
+
key = torch.cat((existing[0], key), dim=2)
|
| 63 |
+
value = torch.cat((existing[1], value), dim=2)
|
| 64 |
+
self.attention[layer_idx] = (key, value)
|
| 65 |
+
return key, value
|
| 66 |
+
|
| 67 |
+
def update_convolution(self, layer_idx: int, state: torch.Tensor) -> None:
|
| 68 |
+
self.convolution[layer_idx] = state
|
| 69 |
+
|
| 70 |
+
def get_convolution(self, layer_idx: int) -> torch.Tensor | None:
|
| 71 |
+
return self.convolution[layer_idx]
|
| 72 |
+
|
| 73 |
+
def finish_step(self, cache_position: torch.Tensor) -> None:
|
| 74 |
+
if cache_position.numel():
|
| 75 |
+
self.seen_tokens = max(self.seen_tokens, int(cache_position.max()) + 1)
|
| 76 |
+
|
| 77 |
+
def reorder_cache(self, beam_idx: torch.LongTensor) -> QyrouArchHybridCache:
|
| 78 |
+
for index, item in enumerate(self.attention):
|
| 79 |
+
if item is not None:
|
| 80 |
+
self.attention[index] = (
|
| 81 |
+
item[0].index_select(0, beam_idx),
|
| 82 |
+
item[1].index_select(0, beam_idx),
|
| 83 |
+
)
|
| 84 |
+
for index, state in enumerate(self.convolution):
|
| 85 |
+
if state is not None:
|
| 86 |
+
self.convolution[index] = state.index_select(0, beam_idx)
|
| 87 |
+
return self
|
| 88 |
+
|
| 89 |
+
def batch_repeat_interleave(self, repeats: int) -> QyrouArchHybridCache:
|
| 90 |
+
indices = torch.arange(
|
| 91 |
+
next(t[0] for t in self.attention if t is not None).shape[0],
|
| 92 |
+
device=next(t[0] for t in self.attention if t is not None).device,
|
| 93 |
+
).repeat_interleave(repeats)
|
| 94 |
+
return self.reorder_cache(indices)
|
| 95 |
+
|
| 96 |
+
def to_legacy_cache(self) -> tuple[Any, ...]:
|
| 97 |
+
return tuple(self.attention)
|
| 98 |
+
|
chat_template.jinja
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{%- for message in messages %}
|
| 2 |
+
{%- if message['role'] not in ['system', 'developer', 'user', 'assistant', 'tool', 'function', 'observation'] %}
|
| 3 |
+
{{- raise_exception('Unsupported QyrouArch chat role: ' + message['role']) }}
|
| 4 |
+
{%- endif %}
|
| 5 |
+
{{- '<|im_start|><|' + message['role'] + '|>\n' + message['content'] + '<|im_end|>\n' }}
|
| 6 |
+
{%- endfor %}
|
| 7 |
+
{%- if add_generation_prompt %}
|
| 8 |
+
{{- '<|im_start|><|assistant|>\n' }}
|
| 9 |
+
{%- endif %}
|
| 10 |
+
|
config.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"architectures": [
|
| 3 |
+
"QyrouArchForCausalLM"
|
| 4 |
+
],
|
| 5 |
+
"attention_backend": "cudnn",
|
| 6 |
+
"auto_map": {
|
| 7 |
+
"AutoConfig": "configuration_qyrou_arch.QyrouArchConfig",
|
| 8 |
+
"AutoModelForCausalLM": "modeling_qyrou_arch.QyrouArchForCausalLM"
|
| 9 |
+
},
|
| 10 |
+
"bos_token_id": 0,
|
| 11 |
+
"conv_kernel_size": 7,
|
| 12 |
+
"conv_layers": [
|
| 13 |
+
4,
|
| 14 |
+
9,
|
| 15 |
+
14,
|
| 16 |
+
19
|
| 17 |
+
],
|
| 18 |
+
"cut_cross_entropy": true,
|
| 19 |
+
"dtype": "float32",
|
| 20 |
+
"eod_token_id": 4,
|
| 21 |
+
"eos_token_id": 1,
|
| 22 |
+
"fused_gate_up_projection": true,
|
| 23 |
+
"fused_qkv_projection": true,
|
| 24 |
+
"hidden_act": "silu",
|
| 25 |
+
"hidden_size": 512,
|
| 26 |
+
"initializer_range": 0.02,
|
| 27 |
+
"intermediate_size": 1328,
|
| 28 |
+
"liger_rms_norm": true,
|
| 29 |
+
"liger_swiglu": true,
|
| 30 |
+
"max_position_embeddings": 2048,
|
| 31 |
+
"model_type": "qyrou_arch",
|
| 32 |
+
"num_attention_heads": 8,
|
| 33 |
+
"num_hidden_layers": 21,
|
| 34 |
+
"num_key_value_heads": 2,
|
| 35 |
+
"pad_token_id": 2,
|
| 36 |
+
"qk_norm": true,
|
| 37 |
+
"residual_initializer_scale": 0.1543033499620919,
|
| 38 |
+
"rms_norm_eps": 1e-05,
|
| 39 |
+
"rope_theta": 10000.0,
|
| 40 |
+
"tie_word_embeddings": true,
|
| 41 |
+
"transformers_version": "5.13.0",
|
| 42 |
+
"unk_token_id": 3,
|
| 43 |
+
"use_cache": true,
|
| 44 |
+
"vocab_size": 20000
|
| 45 |
+
}
|
configuration_qyrou_arch.py
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from typing import Any
|
| 4 |
+
|
| 5 |
+
try:
|
| 6 |
+
from transformers import PretrainedConfig
|
| 7 |
+
except ImportError:
|
| 8 |
+
class PretrainedConfig: # type: ignore[no-redef]
|
| 9 |
+
model_type = "qyrou_arch"
|
| 10 |
+
|
| 11 |
+
def __init__(self, **kwargs: Any) -> None:
|
| 12 |
+
for key, value in kwargs.items():
|
| 13 |
+
setattr(self, key, value)
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
class QyrouArchConfig(PretrainedConfig):
|
| 17 |
+
model_type = "qyrou_arch"
|
| 18 |
+
|
| 19 |
+
def __init__(
|
| 20 |
+
self,
|
| 21 |
+
vocab_size: int = 20_000,
|
| 22 |
+
hidden_size: int = 512,
|
| 23 |
+
num_hidden_layers: int = 21,
|
| 24 |
+
num_attention_heads: int = 8,
|
| 25 |
+
num_key_value_heads: int = 2,
|
| 26 |
+
intermediate_size: int = 1_328,
|
| 27 |
+
conv_layers: list[int] | None = None,
|
| 28 |
+
conv_kernel_size: int = 7,
|
| 29 |
+
rope_theta: float = 10_000.0,
|
| 30 |
+
rms_norm_eps: float = 1e-5,
|
| 31 |
+
max_position_embeddings: int = 2_048,
|
| 32 |
+
initializer_range: float = 0.02,
|
| 33 |
+
residual_initializer_scale: float = 1.0 / (42.0**0.5),
|
| 34 |
+
tie_word_embeddings: bool = True,
|
| 35 |
+
qk_norm: bool = True,
|
| 36 |
+
attention_backend: str = "cudnn",
|
| 37 |
+
fused_qkv_projection: bool = True,
|
| 38 |
+
fused_gate_up_projection: bool = True,
|
| 39 |
+
liger_rms_norm: bool = True,
|
| 40 |
+
liger_swiglu: bool = True,
|
| 41 |
+
cut_cross_entropy: bool = True,
|
| 42 |
+
use_cache: bool = True,
|
| 43 |
+
eod_token_id: int = 4,
|
| 44 |
+
**kwargs: Any,
|
| 45 |
+
) -> None:
|
| 46 |
+
super().__init__(tie_word_embeddings=tie_word_embeddings, **kwargs)
|
| 47 |
+
if hidden_size % num_attention_heads:
|
| 48 |
+
raise ValueError("hidden_size must be divisible by num_attention_heads")
|
| 49 |
+
if num_attention_heads % num_key_value_heads:
|
| 50 |
+
raise ValueError("num_attention_heads must be divisible by num_key_value_heads")
|
| 51 |
+
conv_layers = conv_layers if conv_layers is not None else [4, 9, 14, 19]
|
| 52 |
+
if len(set(conv_layers)) != len(conv_layers) or not all(
|
| 53 |
+
1 <= layer <= num_hidden_layers for layer in conv_layers
|
| 54 |
+
):
|
| 55 |
+
raise ValueError("conv_layers must contain unique one-based layer indices")
|
| 56 |
+
self.vocab_size = vocab_size
|
| 57 |
+
self.hidden_size = hidden_size
|
| 58 |
+
self.num_hidden_layers = num_hidden_layers
|
| 59 |
+
self.num_attention_heads = num_attention_heads
|
| 60 |
+
self.num_key_value_heads = num_key_value_heads
|
| 61 |
+
self.intermediate_size = intermediate_size
|
| 62 |
+
self.conv_layers = conv_layers
|
| 63 |
+
self.conv_kernel_size = conv_kernel_size
|
| 64 |
+
self.rope_theta = rope_theta
|
| 65 |
+
self.rms_norm_eps = rms_norm_eps
|
| 66 |
+
self.max_position_embeddings = max_position_embeddings
|
| 67 |
+
self.initializer_range = initializer_range
|
| 68 |
+
self.residual_initializer_scale = residual_initializer_scale
|
| 69 |
+
self.qk_norm = qk_norm
|
| 70 |
+
self.attention_backend = attention_backend
|
| 71 |
+
self.fused_qkv_projection = fused_qkv_projection
|
| 72 |
+
self.fused_gate_up_projection = fused_gate_up_projection
|
| 73 |
+
self.liger_rms_norm = liger_rms_norm
|
| 74 |
+
self.liger_swiglu = liger_swiglu
|
| 75 |
+
self.cut_cross_entropy = cut_cross_entropy
|
| 76 |
+
self.use_cache = use_cache
|
| 77 |
+
self.eod_token_id = eod_token_id
|
| 78 |
+
self.hidden_act = "silu"
|
| 79 |
+
|
generation_config.json
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"_from_model_config": true,
|
| 3 |
+
"bos_token_id": 0,
|
| 4 |
+
"eos_token_id": 1,
|
| 5 |
+
"output_attentions": false,
|
| 6 |
+
"output_hidden_states": false,
|
| 7 |
+
"pad_token_id": 2,
|
| 8 |
+
"transformers_version": "5.13.0",
|
| 9 |
+
"use_cache": true
|
| 10 |
+
}
|
marker_manifest.json
ADDED
|
@@ -0,0 +1,1190 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"id": 0,
|
| 4 |
+
"token": "<|bos|>",
|
| 5 |
+
"special": true,
|
| 6 |
+
"category": "core"
|
| 7 |
+
},
|
| 8 |
+
{
|
| 9 |
+
"id": 1,
|
| 10 |
+
"token": "<|eos|>",
|
| 11 |
+
"special": true,
|
| 12 |
+
"category": "core"
|
| 13 |
+
},
|
| 14 |
+
{
|
| 15 |
+
"id": 2,
|
| 16 |
+
"token": "<|pad|>",
|
| 17 |
+
"special": true,
|
| 18 |
+
"category": "core"
|
| 19 |
+
},
|
| 20 |
+
{
|
| 21 |
+
"id": 3,
|
| 22 |
+
"token": "<|unk|>",
|
| 23 |
+
"special": true,
|
| 24 |
+
"category": "core"
|
| 25 |
+
},
|
| 26 |
+
{
|
| 27 |
+
"id": 4,
|
| 28 |
+
"token": "<|eod|>",
|
| 29 |
+
"special": true,
|
| 30 |
+
"category": "core"
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"id": 5,
|
| 34 |
+
"token": "<|startoftext|>",
|
| 35 |
+
"special": true,
|
| 36 |
+
"category": "text_boundaries"
|
| 37 |
+
},
|
| 38 |
+
{
|
| 39 |
+
"id": 6,
|
| 40 |
+
"token": "<|endoftext|>",
|
| 41 |
+
"special": true,
|
| 42 |
+
"category": "text_boundaries"
|
| 43 |
+
},
|
| 44 |
+
{
|
| 45 |
+
"id": 7,
|
| 46 |
+
"token": "<|endofprompt|>",
|
| 47 |
+
"special": true,
|
| 48 |
+
"category": "text_boundaries"
|
| 49 |
+
},
|
| 50 |
+
{
|
| 51 |
+
"id": 8,
|
| 52 |
+
"token": "<|im_start|>",
|
| 53 |
+
"special": true,
|
| 54 |
+
"category": "chatml"
|
| 55 |
+
},
|
| 56 |
+
{
|
| 57 |
+
"id": 9,
|
| 58 |
+
"token": "<|im_end|>",
|
| 59 |
+
"special": true,
|
| 60 |
+
"category": "chatml"
|
| 61 |
+
},
|
| 62 |
+
{
|
| 63 |
+
"id": 10,
|
| 64 |
+
"token": "<|system|>",
|
| 65 |
+
"special": true,
|
| 66 |
+
"category": "chatml"
|
| 67 |
+
},
|
| 68 |
+
{
|
| 69 |
+
"id": 11,
|
| 70 |
+
"token": "<|developer|>",
|
| 71 |
+
"special": true,
|
| 72 |
+
"category": "chatml"
|
| 73 |
+
},
|
| 74 |
+
{
|
| 75 |
+
"id": 12,
|
| 76 |
+
"token": "<|user|>",
|
| 77 |
+
"special": true,
|
| 78 |
+
"category": "chatml"
|
| 79 |
+
},
|
| 80 |
+
{
|
| 81 |
+
"id": 13,
|
| 82 |
+
"token": "<|assistant|>",
|
| 83 |
+
"special": true,
|
| 84 |
+
"category": "chatml"
|
| 85 |
+
},
|
| 86 |
+
{
|
| 87 |
+
"id": 14,
|
| 88 |
+
"token": "<|tool|>",
|
| 89 |
+
"special": true,
|
| 90 |
+
"category": "chatml"
|
| 91 |
+
},
|
| 92 |
+
{
|
| 93 |
+
"id": 15,
|
| 94 |
+
"token": "<|function|>",
|
| 95 |
+
"special": true,
|
| 96 |
+
"category": "chatml"
|
| 97 |
+
},
|
| 98 |
+
{
|
| 99 |
+
"id": 16,
|
| 100 |
+
"token": "<|observation|>",
|
| 101 |
+
"special": true,
|
| 102 |
+
"category": "chatml"
|
| 103 |
+
},
|
| 104 |
+
{
|
| 105 |
+
"id": 17,
|
| 106 |
+
"token": "<|eot|>",
|
| 107 |
+
"special": true,
|
| 108 |
+
"category": "chatml"
|
| 109 |
+
},
|
| 110 |
+
{
|
| 111 |
+
"id": 18,
|
| 112 |
+
"token": "<think>",
|
| 113 |
+
"special": false,
|
| 114 |
+
"category": "reasoning"
|
| 115 |
+
},
|
| 116 |
+
{
|
| 117 |
+
"id": 19,
|
| 118 |
+
"token": "</think>",
|
| 119 |
+
"special": false,
|
| 120 |
+
"category": "reasoning"
|
| 121 |
+
},
|
| 122 |
+
{
|
| 123 |
+
"id": 20,
|
| 124 |
+
"token": "<analysis>",
|
| 125 |
+
"special": false,
|
| 126 |
+
"category": "reasoning"
|
| 127 |
+
},
|
| 128 |
+
{
|
| 129 |
+
"id": 21,
|
| 130 |
+
"token": "</analysis>",
|
| 131 |
+
"special": false,
|
| 132 |
+
"category": "reasoning"
|
| 133 |
+
},
|
| 134 |
+
{
|
| 135 |
+
"id": 22,
|
| 136 |
+
"token": "<reasoning>",
|
| 137 |
+
"special": false,
|
| 138 |
+
"category": "reasoning"
|
| 139 |
+
},
|
| 140 |
+
{
|
| 141 |
+
"id": 23,
|
| 142 |
+
"token": "</reasoning>",
|
| 143 |
+
"special": false,
|
| 144 |
+
"category": "reasoning"
|
| 145 |
+
},
|
| 146 |
+
{
|
| 147 |
+
"id": 24,
|
| 148 |
+
"token": "<commentary>",
|
| 149 |
+
"special": false,
|
| 150 |
+
"category": "reasoning"
|
| 151 |
+
},
|
| 152 |
+
{
|
| 153 |
+
"id": 25,
|
| 154 |
+
"token": "</commentary>",
|
| 155 |
+
"special": false,
|
| 156 |
+
"category": "reasoning"
|
| 157 |
+
},
|
| 158 |
+
{
|
| 159 |
+
"id": 26,
|
| 160 |
+
"token": "<final>",
|
| 161 |
+
"special": false,
|
| 162 |
+
"category": "reasoning"
|
| 163 |
+
},
|
| 164 |
+
{
|
| 165 |
+
"id": 27,
|
| 166 |
+
"token": "</final>",
|
| 167 |
+
"special": false,
|
| 168 |
+
"category": "reasoning"
|
| 169 |
+
},
|
| 170 |
+
{
|
| 171 |
+
"id": 28,
|
| 172 |
+
"token": "<tools>",
|
| 173 |
+
"special": false,
|
| 174 |
+
"category": "tools"
|
| 175 |
+
},
|
| 176 |
+
{
|
| 177 |
+
"id": 29,
|
| 178 |
+
"token": "</tools>",
|
| 179 |
+
"special": false,
|
| 180 |
+
"category": "tools"
|
| 181 |
+
},
|
| 182 |
+
{
|
| 183 |
+
"id": 30,
|
| 184 |
+
"token": "<available_tools>",
|
| 185 |
+
"special": false,
|
| 186 |
+
"category": "tools"
|
| 187 |
+
},
|
| 188 |
+
{
|
| 189 |
+
"id": 31,
|
| 190 |
+
"token": "</available_tools>",
|
| 191 |
+
"special": false,
|
| 192 |
+
"category": "tools"
|
| 193 |
+
},
|
| 194 |
+
{
|
| 195 |
+
"id": 32,
|
| 196 |
+
"token": "<tool_call>",
|
| 197 |
+
"special": false,
|
| 198 |
+
"category": "tools"
|
| 199 |
+
},
|
| 200 |
+
{
|
| 201 |
+
"id": 33,
|
| 202 |
+
"token": "</tool_call>",
|
| 203 |
+
"special": false,
|
| 204 |
+
"category": "tools"
|
| 205 |
+
},
|
| 206 |
+
{
|
| 207 |
+
"id": 34,
|
| 208 |
+
"token": "<tool_response>",
|
| 209 |
+
"special": false,
|
| 210 |
+
"category": "tools"
|
| 211 |
+
},
|
| 212 |
+
{
|
| 213 |
+
"id": 35,
|
| 214 |
+
"token": "</tool_response>",
|
| 215 |
+
"special": false,
|
| 216 |
+
"category": "tools"
|
| 217 |
+
},
|
| 218 |
+
{
|
| 219 |
+
"id": 36,
|
| 220 |
+
"token": "<function_call>",
|
| 221 |
+
"special": false,
|
| 222 |
+
"category": "tools"
|
| 223 |
+
},
|
| 224 |
+
{
|
| 225 |
+
"id": 37,
|
| 226 |
+
"token": "</function_call>",
|
| 227 |
+
"special": false,
|
| 228 |
+
"category": "tools"
|
| 229 |
+
},
|
| 230 |
+
{
|
| 231 |
+
"id": 38,
|
| 232 |
+
"token": "<function_response>",
|
| 233 |
+
"special": false,
|
| 234 |
+
"category": "tools"
|
| 235 |
+
},
|
| 236 |
+
{
|
| 237 |
+
"id": 39,
|
| 238 |
+
"token": "</function_response>",
|
| 239 |
+
"special": false,
|
| 240 |
+
"category": "tools"
|
| 241 |
+
},
|
| 242 |
+
{
|
| 243 |
+
"id": 40,
|
| 244 |
+
"token": "<|tool_sep|>",
|
| 245 |
+
"special": false,
|
| 246 |
+
"category": "tools"
|
| 247 |
+
},
|
| 248 |
+
{
|
| 249 |
+
"id": 41,
|
| 250 |
+
"token": "<|fim_prefix|>",
|
| 251 |
+
"special": false,
|
| 252 |
+
"category": "qwen_fim"
|
| 253 |
+
},
|
| 254 |
+
{
|
| 255 |
+
"id": 42,
|
| 256 |
+
"token": "<|fim_middle|>",
|
| 257 |
+
"special": false,
|
| 258 |
+
"category": "qwen_fim"
|
| 259 |
+
},
|
| 260 |
+
{
|
| 261 |
+
"id": 43,
|
| 262 |
+
"token": "<|fim_suffix|>",
|
| 263 |
+
"special": false,
|
| 264 |
+
"category": "qwen_fim"
|
| 265 |
+
},
|
| 266 |
+
{
|
| 267 |
+
"id": 44,
|
| 268 |
+
"token": "<|fim_pad|>",
|
| 269 |
+
"special": false,
|
| 270 |
+
"category": "qwen_fim"
|
| 271 |
+
},
|
| 272 |
+
{
|
| 273 |
+
"id": 45,
|
| 274 |
+
"token": "<|repo_name|>",
|
| 275 |
+
"special": false,
|
| 276 |
+
"category": "qwen_fim"
|
| 277 |
+
},
|
| 278 |
+
{
|
| 279 |
+
"id": 46,
|
| 280 |
+
"token": "<|file_sep|>",
|
| 281 |
+
"special": false,
|
| 282 |
+
"category": "qwen_fim"
|
| 283 |
+
},
|
| 284 |
+
{
|
| 285 |
+
"id": 47,
|
| 286 |
+
"token": "<fim_prefix>",
|
| 287 |
+
"special": false,
|
| 288 |
+
"category": "starcoder"
|
| 289 |
+
},
|
| 290 |
+
{
|
| 291 |
+
"id": 48,
|
| 292 |
+
"token": "<fim_middle>",
|
| 293 |
+
"special": false,
|
| 294 |
+
"category": "starcoder"
|
| 295 |
+
},
|
| 296 |
+
{
|
| 297 |
+
"id": 49,
|
| 298 |
+
"token": "<fim_suffix>",
|
| 299 |
+
"special": false,
|
| 300 |
+
"category": "starcoder"
|
| 301 |
+
},
|
| 302 |
+
{
|
| 303 |
+
"id": 50,
|
| 304 |
+
"token": "<fim_pad>",
|
| 305 |
+
"special": false,
|
| 306 |
+
"category": "starcoder"
|
| 307 |
+
},
|
| 308 |
+
{
|
| 309 |
+
"id": 51,
|
| 310 |
+
"token": "<repo_name>",
|
| 311 |
+
"special": false,
|
| 312 |
+
"category": "starcoder"
|
| 313 |
+
},
|
| 314 |
+
{
|
| 315 |
+
"id": 52,
|
| 316 |
+
"token": "<file_sep>",
|
| 317 |
+
"special": false,
|
| 318 |
+
"category": "starcoder"
|
| 319 |
+
},
|
| 320 |
+
{
|
| 321 |
+
"id": 53,
|
| 322 |
+
"token": "<issue_start>",
|
| 323 |
+
"special": false,
|
| 324 |
+
"category": "starcoder"
|
| 325 |
+
},
|
| 326 |
+
{
|
| 327 |
+
"id": 54,
|
| 328 |
+
"token": "<issue_comment>",
|
| 329 |
+
"special": false,
|
| 330 |
+
"category": "starcoder"
|
| 331 |
+
},
|
| 332 |
+
{
|
| 333 |
+
"id": 55,
|
| 334 |
+
"token": "<issue_closed>",
|
| 335 |
+
"special": false,
|
| 336 |
+
"category": "starcoder"
|
| 337 |
+
},
|
| 338 |
+
{
|
| 339 |
+
"id": 56,
|
| 340 |
+
"token": "<jupyter_start>",
|
| 341 |
+
"special": false,
|
| 342 |
+
"category": "starcoder"
|
| 343 |
+
},
|
| 344 |
+
{
|
| 345 |
+
"id": 57,
|
| 346 |
+
"token": "<jupyter_text>",
|
| 347 |
+
"special": false,
|
| 348 |
+
"category": "starcoder"
|
| 349 |
+
},
|
| 350 |
+
{
|
| 351 |
+
"id": 58,
|
| 352 |
+
"token": "<jupyter_code>",
|
| 353 |
+
"special": false,
|
| 354 |
+
"category": "starcoder"
|
| 355 |
+
},
|
| 356 |
+
{
|
| 357 |
+
"id": 59,
|
| 358 |
+
"token": "<jupyter_output>",
|
| 359 |
+
"special": false,
|
| 360 |
+
"category": "starcoder"
|
| 361 |
+
},
|
| 362 |
+
{
|
| 363 |
+
"id": 60,
|
| 364 |
+
"token": "<jupyter_script>",
|
| 365 |
+
"special": false,
|
| 366 |
+
"category": "starcoder"
|
| 367 |
+
},
|
| 368 |
+
{
|
| 369 |
+
"id": 61,
|
| 370 |
+
"token": "<empty_output>",
|
| 371 |
+
"special": false,
|
| 372 |
+
"category": "starcoder"
|
| 373 |
+
},
|
| 374 |
+
{
|
| 375 |
+
"id": 62,
|
| 376 |
+
"token": "<|begin_of_text|>",
|
| 377 |
+
"special": true,
|
| 378 |
+
"category": "llama"
|
| 379 |
+
},
|
| 380 |
+
{
|
| 381 |
+
"id": 63,
|
| 382 |
+
"token": "<|end_of_text|>",
|
| 383 |
+
"special": true,
|
| 384 |
+
"category": "llama"
|
| 385 |
+
},
|
| 386 |
+
{
|
| 387 |
+
"id": 64,
|
| 388 |
+
"token": "<|start_header_id|>",
|
| 389 |
+
"special": true,
|
| 390 |
+
"category": "llama"
|
| 391 |
+
},
|
| 392 |
+
{
|
| 393 |
+
"id": 65,
|
| 394 |
+
"token": "<|end_header_id|>",
|
| 395 |
+
"special": true,
|
| 396 |
+
"category": "llama"
|
| 397 |
+
},
|
| 398 |
+
{
|
| 399 |
+
"id": 66,
|
| 400 |
+
"token": "<|eot_id|>",
|
| 401 |
+
"special": true,
|
| 402 |
+
"category": "llama"
|
| 403 |
+
},
|
| 404 |
+
{
|
| 405 |
+
"id": 67,
|
| 406 |
+
"token": "<|eom_id|>",
|
| 407 |
+
"special": true,
|
| 408 |
+
"category": "llama"
|
| 409 |
+
},
|
| 410 |
+
{
|
| 411 |
+
"id": 68,
|
| 412 |
+
"token": "<|python_tag|>",
|
| 413 |
+
"special": true,
|
| 414 |
+
"category": "llama"
|
| 415 |
+
},
|
| 416 |
+
{
|
| 417 |
+
"id": 69,
|
| 418 |
+
"token": "<start_of_turn>",
|
| 419 |
+
"special": true,
|
| 420 |
+
"category": "gemma"
|
| 421 |
+
},
|
| 422 |
+
{
|
| 423 |
+
"id": 70,
|
| 424 |
+
"token": "<end_of_turn>",
|
| 425 |
+
"special": true,
|
| 426 |
+
"category": "gemma"
|
| 427 |
+
},
|
| 428 |
+
{
|
| 429 |
+
"id": 71,
|
| 430 |
+
"token": "<start_of_image>",
|
| 431 |
+
"special": true,
|
| 432 |
+
"category": "gemma"
|
| 433 |
+
},
|
| 434 |
+
{
|
| 435 |
+
"id": 72,
|
| 436 |
+
"token": "<s>",
|
| 437 |
+
"special": true,
|
| 438 |
+
"category": "mistral"
|
| 439 |
+
},
|
| 440 |
+
{
|
| 441 |
+
"id": 73,
|
| 442 |
+
"token": "</s>",
|
| 443 |
+
"special": true,
|
| 444 |
+
"category": "mistral"
|
| 445 |
+
},
|
| 446 |
+
{
|
| 447 |
+
"id": 74,
|
| 448 |
+
"token": "<unk>",
|
| 449 |
+
"special": true,
|
| 450 |
+
"category": "mistral"
|
| 451 |
+
},
|
| 452 |
+
{
|
| 453 |
+
"id": 75,
|
| 454 |
+
"token": "<pad>",
|
| 455 |
+
"special": true,
|
| 456 |
+
"category": "mistral"
|
| 457 |
+
},
|
| 458 |
+
{
|
| 459 |
+
"id": 76,
|
| 460 |
+
"token": "[INST]",
|
| 461 |
+
"special": true,
|
| 462 |
+
"category": "mistral"
|
| 463 |
+
},
|
| 464 |
+
{
|
| 465 |
+
"id": 77,
|
| 466 |
+
"token": "[/INST]",
|
| 467 |
+
"special": true,
|
| 468 |
+
"category": "mistral"
|
| 469 |
+
},
|
| 470 |
+
{
|
| 471 |
+
"id": 78,
|
| 472 |
+
"token": "[AVAILABLE_TOOLS]",
|
| 473 |
+
"special": true,
|
| 474 |
+
"category": "mistral"
|
| 475 |
+
},
|
| 476 |
+
{
|
| 477 |
+
"id": 79,
|
| 478 |
+
"token": "[/AVAILABLE_TOOLS]",
|
| 479 |
+
"special": true,
|
| 480 |
+
"category": "mistral"
|
| 481 |
+
},
|
| 482 |
+
{
|
| 483 |
+
"id": 80,
|
| 484 |
+
"token": "[TOOL_CALLS]",
|
| 485 |
+
"special": true,
|
| 486 |
+
"category": "mistral"
|
| 487 |
+
},
|
| 488 |
+
{
|
| 489 |
+
"id": 81,
|
| 490 |
+
"token": "[TOOL_RESULTS]",
|
| 491 |
+
"special": true,
|
| 492 |
+
"category": "mistral"
|
| 493 |
+
},
|
| 494 |
+
{
|
| 495 |
+
"id": 82,
|
| 496 |
+
"token": "[/TOOL_RESULTS]",
|
| 497 |
+
"special": true,
|
| 498 |
+
"category": "mistral"
|
| 499 |
+
},
|
| 500 |
+
{
|
| 501 |
+
"id": 83,
|
| 502 |
+
"token": "[SYSTEM_PROMPT]",
|
| 503 |
+
"special": true,
|
| 504 |
+
"category": "mistral"
|
| 505 |
+
},
|
| 506 |
+
{
|
| 507 |
+
"id": 84,
|
| 508 |
+
"token": "[/SYSTEM_PROMPT]",
|
| 509 |
+
"special": true,
|
| 510 |
+
"category": "mistral"
|
| 511 |
+
},
|
| 512 |
+
{
|
| 513 |
+
"id": 85,
|
| 514 |
+
"token": "[TOOL_CONTENT]",
|
| 515 |
+
"special": true,
|
| 516 |
+
"category": "mistral"
|
| 517 |
+
},
|
| 518 |
+
{
|
| 519 |
+
"id": 86,
|
| 520 |
+
"token": "[ARGS]",
|
| 521 |
+
"special": true,
|
| 522 |
+
"category": "mistral"
|
| 523 |
+
},
|
| 524 |
+
{
|
| 525 |
+
"id": 87,
|
| 526 |
+
"token": "[CALL_ID]",
|
| 527 |
+
"special": true,
|
| 528 |
+
"category": "mistral"
|
| 529 |
+
},
|
| 530 |
+
{
|
| 531 |
+
"id": 88,
|
| 532 |
+
"token": "[PREFIX]",
|
| 533 |
+
"special": true,
|
| 534 |
+
"category": "mistral"
|
| 535 |
+
},
|
| 536 |
+
{
|
| 537 |
+
"id": 89,
|
| 538 |
+
"token": "[MIDDLE]",
|
| 539 |
+
"special": true,
|
| 540 |
+
"category": "mistral"
|
| 541 |
+
},
|
| 542 |
+
{
|
| 543 |
+
"id": 90,
|
| 544 |
+
"token": "[SUFFIX]",
|
| 545 |
+
"special": true,
|
| 546 |
+
"category": "mistral"
|
| 547 |
+
},
|
| 548 |
+
{
|
| 549 |
+
"id": 91,
|
| 550 |
+
"token": "[THINK]",
|
| 551 |
+
"special": true,
|
| 552 |
+
"category": "mistral"
|
| 553 |
+
},
|
| 554 |
+
{
|
| 555 |
+
"id": 92,
|
| 556 |
+
"token": "[/THINK]",
|
| 557 |
+
"special": true,
|
| 558 |
+
"category": "mistral"
|
| 559 |
+
},
|
| 560 |
+
{
|
| 561 |
+
"id": 93,
|
| 562 |
+
"token": "[MODEL_SETTINGS]",
|
| 563 |
+
"special": true,
|
| 564 |
+
"category": "mistral"
|
| 565 |
+
},
|
| 566 |
+
{
|
| 567 |
+
"id": 94,
|
| 568 |
+
"token": "[/MODEL_SETTINGS]",
|
| 569 |
+
"special": true,
|
| 570 |
+
"category": "mistral"
|
| 571 |
+
},
|
| 572 |
+
{
|
| 573 |
+
"id": 95,
|
| 574 |
+
"token": "<|begin▁of▁sentence|>",
|
| 575 |
+
"special": true,
|
| 576 |
+
"category": "deepseek"
|
| 577 |
+
},
|
| 578 |
+
{
|
| 579 |
+
"id": 96,
|
| 580 |
+
"token": "<|end▁of▁sentence|>",
|
| 581 |
+
"special": true,
|
| 582 |
+
"category": "deepseek"
|
| 583 |
+
},
|
| 584 |
+
{
|
| 585 |
+
"id": 97,
|
| 586 |
+
"token": "<|User|>",
|
| 587 |
+
"special": true,
|
| 588 |
+
"category": "deepseek"
|
| 589 |
+
},
|
| 590 |
+
{
|
| 591 |
+
"id": 98,
|
| 592 |
+
"token": "<|Assistant|>",
|
| 593 |
+
"special": true,
|
| 594 |
+
"category": "deepseek"
|
| 595 |
+
},
|
| 596 |
+
{
|
| 597 |
+
"id": 99,
|
| 598 |
+
"token": "<|tool▁calls▁begin|>",
|
| 599 |
+
"special": true,
|
| 600 |
+
"category": "deepseek"
|
| 601 |
+
},
|
| 602 |
+
{
|
| 603 |
+
"id": 100,
|
| 604 |
+
"token": "<|tool▁call▁begin|>",
|
| 605 |
+
"special": true,
|
| 606 |
+
"category": "deepseek"
|
| 607 |
+
},
|
| 608 |
+
{
|
| 609 |
+
"id": 101,
|
| 610 |
+
"token": "<|tool▁sep|>",
|
| 611 |
+
"special": true,
|
| 612 |
+
"category": "deepseek"
|
| 613 |
+
},
|
| 614 |
+
{
|
| 615 |
+
"id": 102,
|
| 616 |
+
"token": "<|tool▁call▁end|>",
|
| 617 |
+
"special": true,
|
| 618 |
+
"category": "deepseek"
|
| 619 |
+
},
|
| 620 |
+
{
|
| 621 |
+
"id": 103,
|
| 622 |
+
"token": "<|tool▁calls▁end|>",
|
| 623 |
+
"special": true,
|
| 624 |
+
"category": "deepseek"
|
| 625 |
+
},
|
| 626 |
+
{
|
| 627 |
+
"id": 104,
|
| 628 |
+
"token": "<|tool▁outputs▁begin|>",
|
| 629 |
+
"special": true,
|
| 630 |
+
"category": "deepseek"
|
| 631 |
+
},
|
| 632 |
+
{
|
| 633 |
+
"id": 105,
|
| 634 |
+
"token": "<|tool▁output▁begin|>",
|
| 635 |
+
"special": true,
|
| 636 |
+
"category": "deepseek"
|
| 637 |
+
},
|
| 638 |
+
{
|
| 639 |
+
"id": 106,
|
| 640 |
+
"token": "<|tool▁output▁end|>",
|
| 641 |
+
"special": true,
|
| 642 |
+
"category": "deepseek"
|
| 643 |
+
},
|
| 644 |
+
{
|
| 645 |
+
"id": 107,
|
| 646 |
+
"token": "<|tool▁outputs▁end|>",
|
| 647 |
+
"special": true,
|
| 648 |
+
"category": "deepseek"
|
| 649 |
+
},
|
| 650 |
+
{
|
| 651 |
+
"id": 108,
|
| 652 |
+
"token": "<|fim▁begin|>",
|
| 653 |
+
"special": true,
|
| 654 |
+
"category": "deepseek"
|
| 655 |
+
},
|
| 656 |
+
{
|
| 657 |
+
"id": 109,
|
| 658 |
+
"token": "<|fim▁hole|>",
|
| 659 |
+
"special": true,
|
| 660 |
+
"category": "deepseek"
|
| 661 |
+
},
|
| 662 |
+
{
|
| 663 |
+
"id": 110,
|
| 664 |
+
"token": "<|fim▁end|>",
|
| 665 |
+
"special": true,
|
| 666 |
+
"category": "deepseek"
|
| 667 |
+
},
|
| 668 |
+
{
|
| 669 |
+
"id": 111,
|
| 670 |
+
"token": "<|start|>",
|
| 671 |
+
"special": true,
|
| 672 |
+
"category": "harmony"
|
| 673 |
+
},
|
| 674 |
+
{
|
| 675 |
+
"id": 112,
|
| 676 |
+
"token": "<|end|>",
|
| 677 |
+
"special": true,
|
| 678 |
+
"category": "harmony"
|
| 679 |
+
},
|
| 680 |
+
{
|
| 681 |
+
"id": 113,
|
| 682 |
+
"token": "<|message|>",
|
| 683 |
+
"special": true,
|
| 684 |
+
"category": "harmony"
|
| 685 |
+
},
|
| 686 |
+
{
|
| 687 |
+
"id": 114,
|
| 688 |
+
"token": "<|channel|>",
|
| 689 |
+
"special": true,
|
| 690 |
+
"category": "harmony"
|
| 691 |
+
},
|
| 692 |
+
{
|
| 693 |
+
"id": 115,
|
| 694 |
+
"token": "<|constrain|>",
|
| 695 |
+
"special": true,
|
| 696 |
+
"category": "harmony"
|
| 697 |
+
},
|
| 698 |
+
{
|
| 699 |
+
"id": 116,
|
| 700 |
+
"token": "<|return|>",
|
| 701 |
+
"special": true,
|
| 702 |
+
"category": "harmony"
|
| 703 |
+
},
|
| 704 |
+
{
|
| 705 |
+
"id": 117,
|
| 706 |
+
"token": "<|call|>",
|
| 707 |
+
"special": true,
|
| 708 |
+
"category": "harmony"
|
| 709 |
+
},
|
| 710 |
+
{
|
| 711 |
+
"id": 118,
|
| 712 |
+
"token": "<|vision_start|>",
|
| 713 |
+
"special": true,
|
| 714 |
+
"category": "vision"
|
| 715 |
+
},
|
| 716 |
+
{
|
| 717 |
+
"id": 119,
|
| 718 |
+
"token": "<|vision_end|>",
|
| 719 |
+
"special": true,
|
| 720 |
+
"category": "vision"
|
| 721 |
+
},
|
| 722 |
+
{
|
| 723 |
+
"id": 120,
|
| 724 |
+
"token": "<|vision_pad|>",
|
| 725 |
+
"special": true,
|
| 726 |
+
"category": "vision"
|
| 727 |
+
},
|
| 728 |
+
{
|
| 729 |
+
"id": 121,
|
| 730 |
+
"token": "<|image_pad|>",
|
| 731 |
+
"special": true,
|
| 732 |
+
"category": "vision"
|
| 733 |
+
},
|
| 734 |
+
{
|
| 735 |
+
"id": 122,
|
| 736 |
+
"token": "<|video_pad|>",
|
| 737 |
+
"special": true,
|
| 738 |
+
"category": "vision"
|
| 739 |
+
},
|
| 740 |
+
{
|
| 741 |
+
"id": 123,
|
| 742 |
+
"token": "<|image|>",
|
| 743 |
+
"special": true,
|
| 744 |
+
"category": "vision"
|
| 745 |
+
},
|
| 746 |
+
{
|
| 747 |
+
"id": 124,
|
| 748 |
+
"token": "<|video|>",
|
| 749 |
+
"special": true,
|
| 750 |
+
"category": "vision"
|
| 751 |
+
},
|
| 752 |
+
{
|
| 753 |
+
"id": 125,
|
| 754 |
+
"token": "[IMG]",
|
| 755 |
+
"special": true,
|
| 756 |
+
"category": "vision"
|
| 757 |
+
},
|
| 758 |
+
{
|
| 759 |
+
"id": 126,
|
| 760 |
+
"token": "[IMG_BREAK]",
|
| 761 |
+
"special": true,
|
| 762 |
+
"category": "vision"
|
| 763 |
+
},
|
| 764 |
+
{
|
| 765 |
+
"id": 127,
|
| 766 |
+
"token": "[IMG_END]",
|
| 767 |
+
"special": true,
|
| 768 |
+
"category": "vision"
|
| 769 |
+
},
|
| 770 |
+
{
|
| 771 |
+
"id": 128,
|
| 772 |
+
"token": "<|audio_bos|>",
|
| 773 |
+
"special": true,
|
| 774 |
+
"category": "audio"
|
| 775 |
+
},
|
| 776 |
+
{
|
| 777 |
+
"id": 129,
|
| 778 |
+
"token": "<|AUDIO|>",
|
| 779 |
+
"special": true,
|
| 780 |
+
"category": "audio"
|
| 781 |
+
},
|
| 782 |
+
{
|
| 783 |
+
"id": 130,
|
| 784 |
+
"token": "<|audio_eos|>",
|
| 785 |
+
"special": true,
|
| 786 |
+
"category": "audio"
|
| 787 |
+
},
|
| 788 |
+
{
|
| 789 |
+
"id": 131,
|
| 790 |
+
"token": "<|audio_pad|>",
|
| 791 |
+
"special": true,
|
| 792 |
+
"category": "audio"
|
| 793 |
+
},
|
| 794 |
+
{
|
| 795 |
+
"id": 132,
|
| 796 |
+
"token": "[AUDIO]",
|
| 797 |
+
"special": true,
|
| 798 |
+
"category": "audio"
|
| 799 |
+
},
|
| 800 |
+
{
|
| 801 |
+
"id": 133,
|
| 802 |
+
"token": "[BEGIN_AUDIO]",
|
| 803 |
+
"special": true,
|
| 804 |
+
"category": "audio"
|
| 805 |
+
},
|
| 806 |
+
{
|
| 807 |
+
"id": 134,
|
| 808 |
+
"token": "<|reserved_000|>",
|
| 809 |
+
"special": true,
|
| 810 |
+
"category": "reserved"
|
| 811 |
+
},
|
| 812 |
+
{
|
| 813 |
+
"id": 135,
|
| 814 |
+
"token": "<|reserved_001|>",
|
| 815 |
+
"special": true,
|
| 816 |
+
"category": "reserved"
|
| 817 |
+
},
|
| 818 |
+
{
|
| 819 |
+
"id": 136,
|
| 820 |
+
"token": "<|reserved_002|>",
|
| 821 |
+
"special": true,
|
| 822 |
+
"category": "reserved"
|
| 823 |
+
},
|
| 824 |
+
{
|
| 825 |
+
"id": 137,
|
| 826 |
+
"token": "<|reserved_003|>",
|
| 827 |
+
"special": true,
|
| 828 |
+
"category": "reserved"
|
| 829 |
+
},
|
| 830 |
+
{
|
| 831 |
+
"id": 138,
|
| 832 |
+
"token": "<|reserved_004|>",
|
| 833 |
+
"special": true,
|
| 834 |
+
"category": "reserved"
|
| 835 |
+
},
|
| 836 |
+
{
|
| 837 |
+
"id": 139,
|
| 838 |
+
"token": "<|reserved_005|>",
|
| 839 |
+
"special": true,
|
| 840 |
+
"category": "reserved"
|
| 841 |
+
},
|
| 842 |
+
{
|
| 843 |
+
"id": 140,
|
| 844 |
+
"token": "<|reserved_006|>",
|
| 845 |
+
"special": true,
|
| 846 |
+
"category": "reserved"
|
| 847 |
+
},
|
| 848 |
+
{
|
| 849 |
+
"id": 141,
|
| 850 |
+
"token": "<|reserved_007|>",
|
| 851 |
+
"special": true,
|
| 852 |
+
"category": "reserved"
|
| 853 |
+
},
|
| 854 |
+
{
|
| 855 |
+
"id": 142,
|
| 856 |
+
"token": "<|reserved_008|>",
|
| 857 |
+
"special": true,
|
| 858 |
+
"category": "reserved"
|
| 859 |
+
},
|
| 860 |
+
{
|
| 861 |
+
"id": 143,
|
| 862 |
+
"token": "<|reserved_009|>",
|
| 863 |
+
"special": true,
|
| 864 |
+
"category": "reserved"
|
| 865 |
+
},
|
| 866 |
+
{
|
| 867 |
+
"id": 144,
|
| 868 |
+
"token": "<|reserved_010|>",
|
| 869 |
+
"special": true,
|
| 870 |
+
"category": "reserved"
|
| 871 |
+
},
|
| 872 |
+
{
|
| 873 |
+
"id": 145,
|
| 874 |
+
"token": "<|reserved_011|>",
|
| 875 |
+
"special": true,
|
| 876 |
+
"category": "reserved"
|
| 877 |
+
},
|
| 878 |
+
{
|
| 879 |
+
"id": 146,
|
| 880 |
+
"token": "<|reserved_012|>",
|
| 881 |
+
"special": true,
|
| 882 |
+
"category": "reserved"
|
| 883 |
+
},
|
| 884 |
+
{
|
| 885 |
+
"id": 147,
|
| 886 |
+
"token": "<|reserved_013|>",
|
| 887 |
+
"special": true,
|
| 888 |
+
"category": "reserved"
|
| 889 |
+
},
|
| 890 |
+
{
|
| 891 |
+
"id": 148,
|
| 892 |
+
"token": "<|reserved_014|>",
|
| 893 |
+
"special": true,
|
| 894 |
+
"category": "reserved"
|
| 895 |
+
},
|
| 896 |
+
{
|
| 897 |
+
"id": 149,
|
| 898 |
+
"token": "<|reserved_015|>",
|
| 899 |
+
"special": true,
|
| 900 |
+
"category": "reserved"
|
| 901 |
+
},
|
| 902 |
+
{
|
| 903 |
+
"id": 150,
|
| 904 |
+
"token": "<|reserved_016|>",
|
| 905 |
+
"special": true,
|
| 906 |
+
"category": "reserved"
|
| 907 |
+
},
|
| 908 |
+
{
|
| 909 |
+
"id": 151,
|
| 910 |
+
"token": "<|reserved_017|>",
|
| 911 |
+
"special": true,
|
| 912 |
+
"category": "reserved"
|
| 913 |
+
},
|
| 914 |
+
{
|
| 915 |
+
"id": 152,
|
| 916 |
+
"token": "<|reserved_018|>",
|
| 917 |
+
"special": true,
|
| 918 |
+
"category": "reserved"
|
| 919 |
+
},
|
| 920 |
+
{
|
| 921 |
+
"id": 153,
|
| 922 |
+
"token": "<|reserved_019|>",
|
| 923 |
+
"special": true,
|
| 924 |
+
"category": "reserved"
|
| 925 |
+
},
|
| 926 |
+
{
|
| 927 |
+
"id": 154,
|
| 928 |
+
"token": "<|reserved_020|>",
|
| 929 |
+
"special": true,
|
| 930 |
+
"category": "reserved"
|
| 931 |
+
},
|
| 932 |
+
{
|
| 933 |
+
"id": 155,
|
| 934 |
+
"token": "<|reserved_021|>",
|
| 935 |
+
"special": true,
|
| 936 |
+
"category": "reserved"
|
| 937 |
+
},
|
| 938 |
+
{
|
| 939 |
+
"id": 156,
|
| 940 |
+
"token": "<|reserved_022|>",
|
| 941 |
+
"special": true,
|
| 942 |
+
"category": "reserved"
|
| 943 |
+
},
|
| 944 |
+
{
|
| 945 |
+
"id": 157,
|
| 946 |
+
"token": "<|reserved_023|>",
|
| 947 |
+
"special": true,
|
| 948 |
+
"category": "reserved"
|
| 949 |
+
},
|
| 950 |
+
{
|
| 951 |
+
"id": 158,
|
| 952 |
+
"token": "<|reserved_024|>",
|
| 953 |
+
"special": true,
|
| 954 |
+
"category": "reserved"
|
| 955 |
+
},
|
| 956 |
+
{
|
| 957 |
+
"id": 159,
|
| 958 |
+
"token": "<|reserved_025|>",
|
| 959 |
+
"special": true,
|
| 960 |
+
"category": "reserved"
|
| 961 |
+
},
|
| 962 |
+
{
|
| 963 |
+
"id": 160,
|
| 964 |
+
"token": "<|reserved_026|>",
|
| 965 |
+
"special": true,
|
| 966 |
+
"category": "reserved"
|
| 967 |
+
},
|
| 968 |
+
{
|
| 969 |
+
"id": 161,
|
| 970 |
+
"token": "<|reserved_027|>",
|
| 971 |
+
"special": true,
|
| 972 |
+
"category": "reserved"
|
| 973 |
+
},
|
| 974 |
+
{
|
| 975 |
+
"id": 162,
|
| 976 |
+
"token": "<|reserved_028|>",
|
| 977 |
+
"special": true,
|
| 978 |
+
"category": "reserved"
|
| 979 |
+
},
|
| 980 |
+
{
|
| 981 |
+
"id": 163,
|
| 982 |
+
"token": "<|reserved_029|>",
|
| 983 |
+
"special": true,
|
| 984 |
+
"category": "reserved"
|
| 985 |
+
},
|
| 986 |
+
{
|
| 987 |
+
"id": 164,
|
| 988 |
+
"token": "<|reserved_030|>",
|
| 989 |
+
"special": true,
|
| 990 |
+
"category": "reserved"
|
| 991 |
+
},
|
| 992 |
+
{
|
| 993 |
+
"id": 165,
|
| 994 |
+
"token": "<|reserved_031|>",
|
| 995 |
+
"special": true,
|
| 996 |
+
"category": "reserved"
|
| 997 |
+
},
|
| 998 |
+
{
|
| 999 |
+
"id": 166,
|
| 1000 |
+
"token": "<|reserved_032|>",
|
| 1001 |
+
"special": true,
|
| 1002 |
+
"category": "reserved"
|
| 1003 |
+
},
|
| 1004 |
+
{
|
| 1005 |
+
"id": 167,
|
| 1006 |
+
"token": "<|reserved_033|>",
|
| 1007 |
+
"special": true,
|
| 1008 |
+
"category": "reserved"
|
| 1009 |
+
},
|
| 1010 |
+
{
|
| 1011 |
+
"id": 168,
|
| 1012 |
+
"token": "<|reserved_034|>",
|
| 1013 |
+
"special": true,
|
| 1014 |
+
"category": "reserved"
|
| 1015 |
+
},
|
| 1016 |
+
{
|
| 1017 |
+
"id": 169,
|
| 1018 |
+
"token": "<|reserved_035|>",
|
| 1019 |
+
"special": true,
|
| 1020 |
+
"category": "reserved"
|
| 1021 |
+
},
|
| 1022 |
+
{
|
| 1023 |
+
"id": 170,
|
| 1024 |
+
"token": "<|reserved_036|>",
|
| 1025 |
+
"special": true,
|
| 1026 |
+
"category": "reserved"
|
| 1027 |
+
},
|
| 1028 |
+
{
|
| 1029 |
+
"id": 171,
|
| 1030 |
+
"token": "<|reserved_037|>",
|
| 1031 |
+
"special": true,
|
| 1032 |
+
"category": "reserved"
|
| 1033 |
+
},
|
| 1034 |
+
{
|
| 1035 |
+
"id": 172,
|
| 1036 |
+
"token": "<|reserved_038|>",
|
| 1037 |
+
"special": true,
|
| 1038 |
+
"category": "reserved"
|
| 1039 |
+
},
|
| 1040 |
+
{
|
| 1041 |
+
"id": 173,
|
| 1042 |
+
"token": "<|reserved_039|>",
|
| 1043 |
+
"special": true,
|
| 1044 |
+
"category": "reserved"
|
| 1045 |
+
},
|
| 1046 |
+
{
|
| 1047 |
+
"id": 174,
|
| 1048 |
+
"token": "<|reserved_040|>",
|
| 1049 |
+
"special": true,
|
| 1050 |
+
"category": "reserved"
|
| 1051 |
+
},
|
| 1052 |
+
{
|
| 1053 |
+
"id": 175,
|
| 1054 |
+
"token": "<|reserved_041|>",
|
| 1055 |
+
"special": true,
|
| 1056 |
+
"category": "reserved"
|
| 1057 |
+
},
|
| 1058 |
+
{
|
| 1059 |
+
"id": 176,
|
| 1060 |
+
"token": "<|reserved_042|>",
|
| 1061 |
+
"special": true,
|
| 1062 |
+
"category": "reserved"
|
| 1063 |
+
},
|
| 1064 |
+
{
|
| 1065 |
+
"id": 177,
|
| 1066 |
+
"token": "<|reserved_043|>",
|
| 1067 |
+
"special": true,
|
| 1068 |
+
"category": "reserved"
|
| 1069 |
+
},
|
| 1070 |
+
{
|
| 1071 |
+
"id": 178,
|
| 1072 |
+
"token": "<|reserved_044|>",
|
| 1073 |
+
"special": true,
|
| 1074 |
+
"category": "reserved"
|
| 1075 |
+
},
|
| 1076 |
+
{
|
| 1077 |
+
"id": 179,
|
| 1078 |
+
"token": "<|reserved_045|>",
|
| 1079 |
+
"special": true,
|
| 1080 |
+
"category": "reserved"
|
| 1081 |
+
},
|
| 1082 |
+
{
|
| 1083 |
+
"id": 180,
|
| 1084 |
+
"token": "<|reserved_046|>",
|
| 1085 |
+
"special": true,
|
| 1086 |
+
"category": "reserved"
|
| 1087 |
+
},
|
| 1088 |
+
{
|
| 1089 |
+
"id": 181,
|
| 1090 |
+
"token": "<|reserved_047|>",
|
| 1091 |
+
"special": true,
|
| 1092 |
+
"category": "reserved"
|
| 1093 |
+
},
|
| 1094 |
+
{
|
| 1095 |
+
"id": 182,
|
| 1096 |
+
"token": "<|reserved_048|>",
|
| 1097 |
+
"special": true,
|
| 1098 |
+
"category": "reserved"
|
| 1099 |
+
},
|
| 1100 |
+
{
|
| 1101 |
+
"id": 183,
|
| 1102 |
+
"token": "<|reserved_049|>",
|
| 1103 |
+
"special": true,
|
| 1104 |
+
"category": "reserved"
|
| 1105 |
+
},
|
| 1106 |
+
{
|
| 1107 |
+
"id": 184,
|
| 1108 |
+
"token": "<|reserved_050|>",
|
| 1109 |
+
"special": true,
|
| 1110 |
+
"category": "reserved"
|
| 1111 |
+
},
|
| 1112 |
+
{
|
| 1113 |
+
"id": 185,
|
| 1114 |
+
"token": "<|reserved_051|>",
|
| 1115 |
+
"special": true,
|
| 1116 |
+
"category": "reserved"
|
| 1117 |
+
},
|
| 1118 |
+
{
|
| 1119 |
+
"id": 186,
|
| 1120 |
+
"token": "<|reserved_052|>",
|
| 1121 |
+
"special": true,
|
| 1122 |
+
"category": "reserved"
|
| 1123 |
+
},
|
| 1124 |
+
{
|
| 1125 |
+
"id": 187,
|
| 1126 |
+
"token": "<|reserved_053|>",
|
| 1127 |
+
"special": true,
|
| 1128 |
+
"category": "reserved"
|
| 1129 |
+
},
|
| 1130 |
+
{
|
| 1131 |
+
"id": 188,
|
| 1132 |
+
"token": "<|reserved_054|>",
|
| 1133 |
+
"special": true,
|
| 1134 |
+
"category": "reserved"
|
| 1135 |
+
},
|
| 1136 |
+
{
|
| 1137 |
+
"id": 189,
|
| 1138 |
+
"token": "<|reserved_055|>",
|
| 1139 |
+
"special": true,
|
| 1140 |
+
"category": "reserved"
|
| 1141 |
+
},
|
| 1142 |
+
{
|
| 1143 |
+
"id": 190,
|
| 1144 |
+
"token": "<|reserved_056|>",
|
| 1145 |
+
"special": true,
|
| 1146 |
+
"category": "reserved"
|
| 1147 |
+
},
|
| 1148 |
+
{
|
| 1149 |
+
"id": 191,
|
| 1150 |
+
"token": "<|reserved_057|>",
|
| 1151 |
+
"special": true,
|
| 1152 |
+
"category": "reserved"
|
| 1153 |
+
},
|
| 1154 |
+
{
|
| 1155 |
+
"id": 192,
|
| 1156 |
+
"token": "<|reserved_058|>",
|
| 1157 |
+
"special": true,
|
| 1158 |
+
"category": "reserved"
|
| 1159 |
+
},
|
| 1160 |
+
{
|
| 1161 |
+
"id": 193,
|
| 1162 |
+
"token": "<|reserved_059|>",
|
| 1163 |
+
"special": true,
|
| 1164 |
+
"category": "reserved"
|
| 1165 |
+
},
|
| 1166 |
+
{
|
| 1167 |
+
"id": 194,
|
| 1168 |
+
"token": "<|reserved_060|>",
|
| 1169 |
+
"special": true,
|
| 1170 |
+
"category": "reserved"
|
| 1171 |
+
},
|
| 1172 |
+
{
|
| 1173 |
+
"id": 195,
|
| 1174 |
+
"token": "<|reserved_061|>",
|
| 1175 |
+
"special": true,
|
| 1176 |
+
"category": "reserved"
|
| 1177 |
+
},
|
| 1178 |
+
{
|
| 1179 |
+
"id": 196,
|
| 1180 |
+
"token": "<|reserved_062|>",
|
| 1181 |
+
"special": true,
|
| 1182 |
+
"category": "reserved"
|
| 1183 |
+
},
|
| 1184 |
+
{
|
| 1185 |
+
"id": 197,
|
| 1186 |
+
"token": "<|reserved_063|>",
|
| 1187 |
+
"special": true,
|
| 1188 |
+
"category": "reserved"
|
| 1189 |
+
}
|
| 1190 |
+
]
|
model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:15e793a9c28db4f2c843a4369363170c619ac1c73fdc4e1c98ffef5a9ca07f23
|
| 3 |
+
size 261234016
|
modeling_qyrou_arch.py
ADDED
|
@@ -0,0 +1,504 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from typing import Any
|
| 4 |
+
|
| 5 |
+
import torch
|
| 6 |
+
import torch.nn as nn
|
| 7 |
+
import torch.nn.functional as F
|
| 8 |
+
from torch.nn.attention import SDPBackend, sdpa_kernel
|
| 9 |
+
from transformers import PreTrainedModel
|
| 10 |
+
from transformers.generation import GenerationMixin
|
| 11 |
+
from transformers.modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast
|
| 12 |
+
|
| 13 |
+
from .cache import QyrouArchHybridCache
|
| 14 |
+
from .configuration_qyrou_arch import QyrouArchConfig
|
| 15 |
+
|
| 16 |
+
try:
|
| 17 |
+
from .triton_kernels import PackedSwiGLUFunction
|
| 18 |
+
except (ImportError, RuntimeError):
|
| 19 |
+
PackedSwiGLUFunction = None
|
| 20 |
+
|
| 21 |
+
try:
|
| 22 |
+
from liger_kernel.ops.rms_norm import LigerRMSNormFunction
|
| 23 |
+
from liger_kernel.ops.swiglu import LigerSiLUMulFunction
|
| 24 |
+
except ImportError:
|
| 25 |
+
LigerRMSNormFunction = None
|
| 26 |
+
LigerSiLUMulFunction = None
|
| 27 |
+
|
| 28 |
+
try:
|
| 29 |
+
from cut_cross_entropy import linear_cross_entropy as cut_linear_cross_entropy
|
| 30 |
+
except ImportError:
|
| 31 |
+
cut_linear_cross_entropy = None
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
class RMSNorm(nn.Module):
|
| 35 |
+
def __init__(self, dim: int, eps: float, use_liger: bool = False) -> None:
|
| 36 |
+
super().__init__()
|
| 37 |
+
self.weight = nn.Parameter(torch.ones(dim))
|
| 38 |
+
self.eps = eps
|
| 39 |
+
self.use_liger = use_liger
|
| 40 |
+
|
| 41 |
+
def forward(self, x: torch.Tensor) -> torch.Tensor:
|
| 42 |
+
if (
|
| 43 |
+
x.is_cuda
|
| 44 |
+
and self.use_liger
|
| 45 |
+
and LigerRMSNormFunction is not None
|
| 46 |
+
and not torch.compiler.is_compiling()
|
| 47 |
+
):
|
| 48 |
+
return LigerRMSNormFunction.apply(x, self.weight, self.eps, 0.0, "llama", False, None)
|
| 49 |
+
x_float = x.float()
|
| 50 |
+
normalized = x_float * torch.rsqrt(x_float.square().mean(-1, keepdim=True) + self.eps)
|
| 51 |
+
return normalized.to(x.dtype) * self.weight.to(x.dtype)
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
def _apply_rope(
|
| 55 |
+
x: torch.Tensor,
|
| 56 |
+
cos: torch.Tensor,
|
| 57 |
+
sin: torch.Tensor,
|
| 58 |
+
) -> torch.Tensor:
|
| 59 |
+
even, odd = x[..., 0::2], x[..., 1::2]
|
| 60 |
+
return torch.stack((even * cos - odd * sin, even * sin + odd * cos), dim=-1).flatten(-2)
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def _last_valid_state(
|
| 64 |
+
x: torch.Tensor,
|
| 65 |
+
mask: torch.Tensor | None,
|
| 66 |
+
state_length: int,
|
| 67 |
+
) -> torch.Tensor:
|
| 68 |
+
if state_length == 0:
|
| 69 |
+
return x[:, :0]
|
| 70 |
+
if mask is None:
|
| 71 |
+
return F.pad(x, (0, 0, max(0, state_length - x.shape[1]), 0))[:, -state_length:]
|
| 72 |
+
result = torch.zeros(
|
| 73 |
+
(x.shape[0], state_length, x.shape[2]),
|
| 74 |
+
dtype=x.dtype,
|
| 75 |
+
device=x.device,
|
| 76 |
+
)
|
| 77 |
+
for batch_index in range(x.shape[0]):
|
| 78 |
+
valid = x[batch_index][mask[batch_index].bool()]
|
| 79 |
+
valid = valid[-state_length:]
|
| 80 |
+
result[batch_index, -valid.shape[0] :] = valid
|
| 81 |
+
return result
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
class CausalGQA(nn.Module):
|
| 85 |
+
def __init__(self, config: QyrouArchConfig, layer_idx: int) -> None:
|
| 86 |
+
super().__init__()
|
| 87 |
+
self.layer_idx = layer_idx
|
| 88 |
+
self.num_heads = config.num_attention_heads
|
| 89 |
+
self.num_kv_heads = config.num_key_value_heads
|
| 90 |
+
self.head_dim = config.hidden_size // config.num_attention_heads
|
| 91 |
+
self.q_size = self.num_heads * self.head_dim
|
| 92 |
+
self.kv_size = self.num_kv_heads * self.head_dim
|
| 93 |
+
self.attention_backend = config.attention_backend
|
| 94 |
+
if config.fused_qkv_projection:
|
| 95 |
+
self.qkv_proj = nn.Linear(config.hidden_size, self.q_size + 2 * self.kv_size, bias=False)
|
| 96 |
+
else:
|
| 97 |
+
self.q_proj = nn.Linear(config.hidden_size, self.q_size, bias=False)
|
| 98 |
+
self.k_proj = nn.Linear(config.hidden_size, self.kv_size, bias=False)
|
| 99 |
+
self.v_proj = nn.Linear(config.hidden_size, self.kv_size, bias=False)
|
| 100 |
+
self.o_proj = nn.Linear(config.hidden_size, config.hidden_size, bias=False)
|
| 101 |
+
self.o_proj._qyrou_arch_residual_projection = True # type: ignore[attr-defined]
|
| 102 |
+
self.q_norm = RMSNorm(self.head_dim, config.rms_norm_eps) if config.qk_norm else nn.Identity()
|
| 103 |
+
self.k_norm = RMSNorm(self.head_dim, config.rms_norm_eps) if config.qk_norm else nn.Identity()
|
| 104 |
+
|
| 105 |
+
def forward(
|
| 106 |
+
self,
|
| 107 |
+
x: torch.Tensor,
|
| 108 |
+
rope: tuple[torch.Tensor, torch.Tensor],
|
| 109 |
+
attention_mask: torch.Tensor | None,
|
| 110 |
+
cache: QyrouArchHybridCache | None,
|
| 111 |
+
cache_position: torch.Tensor,
|
| 112 |
+
) -> torch.Tensor:
|
| 113 |
+
batch, query_length, _ = x.shape
|
| 114 |
+
if hasattr(self, "qkv_proj"):
|
| 115 |
+
q, k, v = self.qkv_proj(x).split((self.q_size, self.kv_size, self.kv_size), dim=-1)
|
| 116 |
+
else:
|
| 117 |
+
q, k, v = self.q_proj(x), self.k_proj(x), self.v_proj(x)
|
| 118 |
+
q = q.view(batch, query_length, self.num_heads, self.head_dim).transpose(1, 2)
|
| 119 |
+
k = k.view(batch, query_length, self.num_kv_heads, self.head_dim).transpose(1, 2)
|
| 120 |
+
v = v.view(batch, query_length, self.num_kv_heads, self.head_dim).transpose(1, 2)
|
| 121 |
+
q, k = self.q_norm(q), self.k_norm(k)
|
| 122 |
+
q = _apply_rope(q, *rope)
|
| 123 |
+
k = _apply_rope(k, *rope)
|
| 124 |
+
if cache is not None:
|
| 125 |
+
k, v = cache.update_attention(self.layer_idx, k, v, cache_position)
|
| 126 |
+
key_length = k.shape[2]
|
| 127 |
+
|
| 128 |
+
mask = None
|
| 129 |
+
use_fast_causal = cache is None and attention_mask is None
|
| 130 |
+
if not use_fast_causal:
|
| 131 |
+
key_positions = torch.arange(key_length, device=x.device)
|
| 132 |
+
allowed = key_positions[None, :] <= cache_position[:, None]
|
| 133 |
+
mask = allowed[None, None, :, :].expand(batch, 1, query_length, key_length)
|
| 134 |
+
if attention_mask is not None:
|
| 135 |
+
if attention_mask.shape[-1] < key_length:
|
| 136 |
+
raise ValueError("attention_mask is shorter than the cached key sequence")
|
| 137 |
+
mask = mask & attention_mask[:, None, None, :key_length].bool()
|
| 138 |
+
if q.is_cuda and self.attention_backend in {"cudnn", "flash"}:
|
| 139 |
+
backends = (
|
| 140 |
+
[SDPBackend.CUDNN_ATTENTION, SDPBackend.FLASH_ATTENTION, SDPBackend.MATH]
|
| 141 |
+
if self.attention_backend == "cudnn"
|
| 142 |
+
else [SDPBackend.FLASH_ATTENTION, SDPBackend.CUDNN_ATTENTION, SDPBackend.MATH]
|
| 143 |
+
)
|
| 144 |
+
with sdpa_kernel(
|
| 145 |
+
backends,
|
| 146 |
+
set_priority=True,
|
| 147 |
+
):
|
| 148 |
+
output = F.scaled_dot_product_attention(
|
| 149 |
+
q,
|
| 150 |
+
k,
|
| 151 |
+
v,
|
| 152 |
+
attn_mask=mask,
|
| 153 |
+
is_causal=use_fast_causal,
|
| 154 |
+
enable_gqa=True,
|
| 155 |
+
)
|
| 156 |
+
else:
|
| 157 |
+
output = F.scaled_dot_product_attention(
|
| 158 |
+
q,
|
| 159 |
+
k,
|
| 160 |
+
v,
|
| 161 |
+
attn_mask=mask,
|
| 162 |
+
is_causal=use_fast_causal,
|
| 163 |
+
enable_gqa=True,
|
| 164 |
+
)
|
| 165 |
+
output = output.transpose(1, 2).contiguous().view(batch, query_length, -1)
|
| 166 |
+
return self.o_proj(output)
|
| 167 |
+
|
| 168 |
+
|
| 169 |
+
class CausalConvMixer(nn.Module):
|
| 170 |
+
def __init__(self, config: QyrouArchConfig, layer_idx: int) -> None:
|
| 171 |
+
super().__init__()
|
| 172 |
+
self.layer_idx = layer_idx
|
| 173 |
+
self.kernel_size = config.conv_kernel_size
|
| 174 |
+
self.depthwise = nn.Conv1d(
|
| 175 |
+
config.hidden_size,
|
| 176 |
+
config.hidden_size,
|
| 177 |
+
kernel_size=self.kernel_size,
|
| 178 |
+
groups=config.hidden_size,
|
| 179 |
+
bias=False,
|
| 180 |
+
)
|
| 181 |
+
self.pointwise = nn.Linear(config.hidden_size, config.hidden_size, bias=False)
|
| 182 |
+
self.pointwise._qyrou_arch_residual_projection = True # type: ignore[attr-defined]
|
| 183 |
+
|
| 184 |
+
def forward(
|
| 185 |
+
self,
|
| 186 |
+
x: torch.Tensor,
|
| 187 |
+
_rope: tuple[torch.Tensor, torch.Tensor],
|
| 188 |
+
attention_mask: torch.Tensor | None,
|
| 189 |
+
cache: QyrouArchHybridCache | None,
|
| 190 |
+
_cache_position: torch.Tensor,
|
| 191 |
+
) -> torch.Tensor:
|
| 192 |
+
state_length = self.kernel_size - 1
|
| 193 |
+
query_mask = attention_mask[:, -x.shape[1] :] if attention_mask is not None else None
|
| 194 |
+
if query_mask is not None:
|
| 195 |
+
x = x * query_mask.unsqueeze(-1).to(x.dtype)
|
| 196 |
+
if cache is None:
|
| 197 |
+
conv_input = F.pad(x.transpose(1, 2), (state_length, 0))
|
| 198 |
+
else:
|
| 199 |
+
previous = cache.get_convolution(self.layer_idx)
|
| 200 |
+
if previous is None:
|
| 201 |
+
previous = torch.zeros(
|
| 202 |
+
(x.shape[0], state_length, x.shape[2]),
|
| 203 |
+
dtype=x.dtype,
|
| 204 |
+
device=x.device,
|
| 205 |
+
)
|
| 206 |
+
combined = torch.cat((previous, x), dim=1)
|
| 207 |
+
conv_input = combined.transpose(1, 2)
|
| 208 |
+
combined_mask = None
|
| 209 |
+
if query_mask is not None:
|
| 210 |
+
combined_mask = torch.cat(
|
| 211 |
+
(
|
| 212 |
+
torch.ones(
|
| 213 |
+
(x.shape[0], state_length),
|
| 214 |
+
dtype=query_mask.dtype,
|
| 215 |
+
device=query_mask.device,
|
| 216 |
+
),
|
| 217 |
+
query_mask,
|
| 218 |
+
),
|
| 219 |
+
dim=1,
|
| 220 |
+
)
|
| 221 |
+
cache.update_convolution(
|
| 222 |
+
self.layer_idx,
|
| 223 |
+
_last_valid_state(combined, combined_mask, state_length),
|
| 224 |
+
)
|
| 225 |
+
return self.pointwise(self.depthwise(conv_input).transpose(1, 2))
|
| 226 |
+
|
| 227 |
+
|
| 228 |
+
class SwiGLU(nn.Module):
|
| 229 |
+
def __init__(self, config: QyrouArchConfig) -> None:
|
| 230 |
+
super().__init__()
|
| 231 |
+
self.intermediate_size = config.intermediate_size
|
| 232 |
+
self.use_liger = config.liger_swiglu
|
| 233 |
+
if config.fused_gate_up_projection:
|
| 234 |
+
self.gate_up_proj = nn.Linear(config.hidden_size, 2 * config.intermediate_size, bias=False)
|
| 235 |
+
else:
|
| 236 |
+
self.gate_proj = nn.Linear(config.hidden_size, config.intermediate_size, bias=False)
|
| 237 |
+
self.up_proj = nn.Linear(config.hidden_size, config.intermediate_size, bias=False)
|
| 238 |
+
self.down_proj = nn.Linear(config.intermediate_size, config.hidden_size, bias=False)
|
| 239 |
+
self.down_proj._qyrou_arch_residual_projection = True # type: ignore[attr-defined]
|
| 240 |
+
|
| 241 |
+
def forward(self, x: torch.Tensor) -> torch.Tensor:
|
| 242 |
+
if hasattr(self, "gate_up_proj"):
|
| 243 |
+
packed = self.gate_up_proj(x)
|
| 244 |
+
if (
|
| 245 |
+
packed.is_cuda
|
| 246 |
+
and self.use_liger
|
| 247 |
+
and PackedSwiGLUFunction is not None
|
| 248 |
+
and not torch.compiler.is_compiling()
|
| 249 |
+
):
|
| 250 |
+
return self.down_proj(PackedSwiGLUFunction.apply(packed))
|
| 251 |
+
gate, up = packed.chunk(2, dim=-1)
|
| 252 |
+
else:
|
| 253 |
+
gate, up = self.gate_proj(x), self.up_proj(x)
|
| 254 |
+
if torch.compiler.is_compiling():
|
| 255 |
+
activated = F.silu(gate) * up
|
| 256 |
+
elif x.is_cuda and self.use_liger and LigerSiLUMulFunction is not None:
|
| 257 |
+
activated = LigerSiLUMulFunction.apply(gate, up, 1.0, 1.0)
|
| 258 |
+
else:
|
| 259 |
+
activated = F.silu(gate) * up
|
| 260 |
+
return self.down_proj(activated)
|
| 261 |
+
|
| 262 |
+
|
| 263 |
+
class QyrouArchBlock(nn.Module):
|
| 264 |
+
def __init__(self, config: QyrouArchConfig, layer_idx: int) -> None:
|
| 265 |
+
super().__init__()
|
| 266 |
+
self.mixer_norm = RMSNorm(config.hidden_size, config.rms_norm_eps, config.liger_rms_norm)
|
| 267 |
+
self.ffn_norm = RMSNorm(config.hidden_size, config.rms_norm_eps, config.liger_rms_norm)
|
| 268 |
+
layer_number = layer_idx + 1
|
| 269 |
+
self.mixer = (
|
| 270 |
+
CausalConvMixer(config, layer_idx)
|
| 271 |
+
if layer_number in config.conv_layers
|
| 272 |
+
else CausalGQA(config, layer_idx)
|
| 273 |
+
)
|
| 274 |
+
self.ffn = SwiGLU(config)
|
| 275 |
+
|
| 276 |
+
def forward(
|
| 277 |
+
self,
|
| 278 |
+
x: torch.Tensor,
|
| 279 |
+
rope: tuple[torch.Tensor, torch.Tensor],
|
| 280 |
+
attention_mask: torch.Tensor | None,
|
| 281 |
+
cache: QyrouArchHybridCache | None,
|
| 282 |
+
cache_position: torch.Tensor,
|
| 283 |
+
) -> torch.Tensor:
|
| 284 |
+
x = x + self.mixer(self.mixer_norm(x), rope, attention_mask, cache, cache_position)
|
| 285 |
+
return x + self.ffn(self.ffn_norm(x))
|
| 286 |
+
|
| 287 |
+
|
| 288 |
+
class QyrouArchPreTrainedModel(PreTrainedModel):
|
| 289 |
+
config_class = QyrouArchConfig
|
| 290 |
+
base_model_prefix = "model"
|
| 291 |
+
supports_gradient_checkpointing = False
|
| 292 |
+
_no_split_modules = ["QyrouArchBlock"]
|
| 293 |
+
|
| 294 |
+
def _init_weights(self, module: nn.Module) -> None:
|
| 295 |
+
if isinstance(module, (nn.Linear, nn.Embedding, nn.Conv1d)):
|
| 296 |
+
scale = (
|
| 297 |
+
self.config.residual_initializer_scale
|
| 298 |
+
if getattr(module, "_qyrou_arch_residual_projection", False)
|
| 299 |
+
else 1.0
|
| 300 |
+
)
|
| 301 |
+
nn.init.normal_(module.weight, mean=0.0, std=self.config.initializer_range * scale)
|
| 302 |
+
|
| 303 |
+
|
| 304 |
+
class QyrouArchModel(QyrouArchPreTrainedModel):
|
| 305 |
+
def __init__(self, config: QyrouArchConfig) -> None:
|
| 306 |
+
super().__init__(config)
|
| 307 |
+
self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size)
|
| 308 |
+
self.layers = nn.ModuleList(
|
| 309 |
+
[QyrouArchBlock(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
|
| 310 |
+
)
|
| 311 |
+
self.norm = RMSNorm(config.hidden_size, config.rms_norm_eps, config.liger_rms_norm)
|
| 312 |
+
head_dim = config.hidden_size // config.num_attention_heads
|
| 313 |
+
inv_freq = 1.0 / (
|
| 314 |
+
config.rope_theta ** (torch.arange(0, head_dim, 2).float() / head_dim)
|
| 315 |
+
)
|
| 316 |
+
positions = torch.arange(config.max_position_embeddings, dtype=torch.float32)
|
| 317 |
+
angles = torch.outer(positions, inv_freq)
|
| 318 |
+
self.register_buffer("rope_cos", angles.cos(), persistent=False)
|
| 319 |
+
self.register_buffer("rope_sin", angles.sin(), persistent=False)
|
| 320 |
+
self.post_init()
|
| 321 |
+
|
| 322 |
+
def _rope(
|
| 323 |
+
self,
|
| 324 |
+
position_ids: torch.Tensor,
|
| 325 |
+
dtype: torch.dtype,
|
| 326 |
+
) -> tuple[torch.Tensor, torch.Tensor]:
|
| 327 |
+
if (
|
| 328 |
+
not torch.compiler.is_compiling()
|
| 329 |
+
and int(position_ids.max()) >= self.config.max_position_embeddings
|
| 330 |
+
):
|
| 331 |
+
raise ValueError("Position exceeds max_position_embeddings")
|
| 332 |
+
cos = self.rope_cos[position_ids].to(dtype).unsqueeze(1)
|
| 333 |
+
sin = self.rope_sin[position_ids].to(dtype).unsqueeze(1)
|
| 334 |
+
return cos, sin
|
| 335 |
+
|
| 336 |
+
def forward(
|
| 337 |
+
self,
|
| 338 |
+
input_ids: torch.LongTensor | None = None,
|
| 339 |
+
attention_mask: torch.Tensor | None = None,
|
| 340 |
+
position_ids: torch.LongTensor | None = None,
|
| 341 |
+
past_key_values: QyrouArchHybridCache | None = None,
|
| 342 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 343 |
+
use_cache: bool | None = None,
|
| 344 |
+
cache_position: torch.LongTensor | None = None,
|
| 345 |
+
return_dict: bool | None = None,
|
| 346 |
+
**_: Any,
|
| 347 |
+
) -> BaseModelOutputWithPast | tuple[torch.Tensor, QyrouArchHybridCache | None]:
|
| 348 |
+
if (input_ids is None) == (inputs_embeds is None):
|
| 349 |
+
raise ValueError("Pass exactly one of input_ids or inputs_embeds")
|
| 350 |
+
hidden = self.embed_tokens(input_ids) if inputs_embeds is None else inputs_embeds
|
| 351 |
+
if hidden.is_cuda and torch.is_autocast_enabled("cuda"):
|
| 352 |
+
hidden = hidden.to(torch.get_autocast_dtype("cuda"))
|
| 353 |
+
batch, query_length, _ = hidden.shape
|
| 354 |
+
use_cache = self.config.use_cache if use_cache is None else use_cache
|
| 355 |
+
return_dict = self.config.return_dict if return_dict is None else return_dict
|
| 356 |
+
if use_cache and past_key_values is None:
|
| 357 |
+
past_key_values = QyrouArchHybridCache(self.config.num_hidden_layers)
|
| 358 |
+
cache = past_key_values if use_cache else None
|
| 359 |
+
past_length = cache.get_seq_length() if cache is not None else 0
|
| 360 |
+
if cache_position is None:
|
| 361 |
+
cache_position = torch.arange(
|
| 362 |
+
past_length,
|
| 363 |
+
past_length + query_length,
|
| 364 |
+
device=hidden.device,
|
| 365 |
+
)
|
| 366 |
+
if position_ids is None:
|
| 367 |
+
if attention_mask is not None:
|
| 368 |
+
position_ids = attention_mask.long().cumsum(-1).sub(1).clamp_min(0)[:, -query_length:]
|
| 369 |
+
else:
|
| 370 |
+
position_ids = cache_position.unsqueeze(0).expand(batch, -1)
|
| 371 |
+
rope = self._rope(position_ids, hidden.dtype)
|
| 372 |
+
for layer in self.layers:
|
| 373 |
+
hidden = layer(hidden, rope, attention_mask, cache, cache_position)
|
| 374 |
+
hidden = self.norm(hidden)
|
| 375 |
+
if cache is not None:
|
| 376 |
+
cache.finish_step(cache_position)
|
| 377 |
+
if not return_dict:
|
| 378 |
+
return hidden, cache
|
| 379 |
+
return BaseModelOutputWithPast(last_hidden_state=hidden, past_key_values=cache)
|
| 380 |
+
|
| 381 |
+
|
| 382 |
+
class QyrouArchForCausalLM(QyrouArchPreTrainedModel, GenerationMixin):
|
| 383 |
+
_tied_weights_keys = {"lm_head.weight": "model.embed_tokens.weight"}
|
| 384 |
+
|
| 385 |
+
def __init__(self, config: QyrouArchConfig) -> None:
|
| 386 |
+
super().__init__(config)
|
| 387 |
+
self.model = QyrouArchModel(config)
|
| 388 |
+
self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
|
| 389 |
+
self.post_init()
|
| 390 |
+
self.tie_weights()
|
| 391 |
+
|
| 392 |
+
def get_input_embeddings(self) -> nn.Module:
|
| 393 |
+
return self.model.embed_tokens
|
| 394 |
+
|
| 395 |
+
def set_input_embeddings(self, value: nn.Module) -> None:
|
| 396 |
+
self.model.embed_tokens = value
|
| 397 |
+
|
| 398 |
+
def get_output_embeddings(self) -> nn.Module:
|
| 399 |
+
return self.lm_head
|
| 400 |
+
|
| 401 |
+
def set_output_embeddings(self, value: nn.Module) -> None:
|
| 402 |
+
self.lm_head = value
|
| 403 |
+
|
| 404 |
+
def forward(
|
| 405 |
+
self,
|
| 406 |
+
input_ids: torch.LongTensor | None = None,
|
| 407 |
+
attention_mask: torch.Tensor | None = None,
|
| 408 |
+
position_ids: torch.LongTensor | None = None,
|
| 409 |
+
past_key_values: QyrouArchHybridCache | None = None,
|
| 410 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 411 |
+
labels: torch.LongTensor | None = None,
|
| 412 |
+
use_cache: bool | None = None,
|
| 413 |
+
cache_position: torch.LongTensor | None = None,
|
| 414 |
+
return_logits: bool = True,
|
| 415 |
+
return_dict: bool | None = None,
|
| 416 |
+
**kwargs: Any,
|
| 417 |
+
) -> CausalLMOutputWithPast | tuple[Any, ...]:
|
| 418 |
+
return_dict = self.config.return_dict if return_dict is None else return_dict
|
| 419 |
+
outputs = self.model(
|
| 420 |
+
input_ids=input_ids,
|
| 421 |
+
attention_mask=attention_mask,
|
| 422 |
+
position_ids=position_ids,
|
| 423 |
+
past_key_values=past_key_values,
|
| 424 |
+
inputs_embeds=inputs_embeds,
|
| 425 |
+
use_cache=use_cache,
|
| 426 |
+
cache_position=cache_position,
|
| 427 |
+
return_dict=True,
|
| 428 |
+
**kwargs,
|
| 429 |
+
)
|
| 430 |
+
hidden = outputs.last_hidden_state
|
| 431 |
+
training_loss_only = labels is not None and not return_logits
|
| 432 |
+
logits = None if training_loss_only else self.lm_head(hidden)
|
| 433 |
+
loss = None
|
| 434 |
+
if labels is not None:
|
| 435 |
+
if (
|
| 436 |
+
training_loss_only
|
| 437 |
+
and hidden.is_cuda
|
| 438 |
+
and self.config.cut_cross_entropy
|
| 439 |
+
and cut_linear_cross_entropy is not None
|
| 440 |
+
):
|
| 441 |
+
loss = cut_linear_cross_entropy(
|
| 442 |
+
hidden,
|
| 443 |
+
self.lm_head.weight,
|
| 444 |
+
labels,
|
| 445 |
+
shift=True,
|
| 446 |
+
filter_eps=None,
|
| 447 |
+
)
|
| 448 |
+
else:
|
| 449 |
+
loss_logits = self.lm_head(hidden[:, :-1]).float()
|
| 450 |
+
loss = F.cross_entropy(
|
| 451 |
+
loss_logits.reshape(-1, self.config.vocab_size),
|
| 452 |
+
labels[:, 1:].contiguous().view(-1),
|
| 453 |
+
ignore_index=-100,
|
| 454 |
+
)
|
| 455 |
+
if not return_dict:
|
| 456 |
+
return loss, logits, outputs.past_key_values
|
| 457 |
+
return CausalLMOutputWithPast(
|
| 458 |
+
loss=loss,
|
| 459 |
+
logits=logits,
|
| 460 |
+
past_key_values=outputs.past_key_values,
|
| 461 |
+
)
|
| 462 |
+
|
| 463 |
+
def prepare_inputs_for_generation(
|
| 464 |
+
self,
|
| 465 |
+
input_ids: torch.LongTensor,
|
| 466 |
+
past_key_values: QyrouArchHybridCache | None = None,
|
| 467 |
+
attention_mask: torch.Tensor | None = None,
|
| 468 |
+
cache_position: torch.LongTensor | None = None,
|
| 469 |
+
use_cache: bool = True,
|
| 470 |
+
**kwargs: Any,
|
| 471 |
+
) -> dict[str, Any]:
|
| 472 |
+
past_length = past_key_values.get_seq_length() if past_key_values is not None else 0
|
| 473 |
+
if past_length:
|
| 474 |
+
input_ids = (
|
| 475 |
+
input_ids[:, past_length:]
|
| 476 |
+
if input_ids.shape[1] > past_length
|
| 477 |
+
else input_ids[:, -1:]
|
| 478 |
+
)
|
| 479 |
+
if cache_position is None:
|
| 480 |
+
cache_position = torch.arange(
|
| 481 |
+
past_length,
|
| 482 |
+
past_length + input_ids.shape[1],
|
| 483 |
+
device=input_ids.device,
|
| 484 |
+
)
|
| 485 |
+
elif cache_position.numel() != input_ids.shape[1]:
|
| 486 |
+
cache_position = cache_position[-input_ids.shape[1] :]
|
| 487 |
+
return {
|
| 488 |
+
"input_ids": input_ids,
|
| 489 |
+
"attention_mask": attention_mask,
|
| 490 |
+
"past_key_values": past_key_values,
|
| 491 |
+
"cache_position": cache_position,
|
| 492 |
+
"use_cache": use_cache,
|
| 493 |
+
}
|
| 494 |
+
|
| 495 |
+
def _reorder_cache(
|
| 496 |
+
self,
|
| 497 |
+
past_key_values: QyrouArchHybridCache,
|
| 498 |
+
beam_idx: torch.LongTensor,
|
| 499 |
+
) -> QyrouArchHybridCache:
|
| 500 |
+
return past_key_values.reorder_cache(beam_idx)
|
| 501 |
+
|
| 502 |
+
|
| 503 |
+
QyrouArchConfig.register_for_auto_class()
|
| 504 |
+
QyrouArchForCausalLM.register_for_auto_class("AutoModelForCausalLM")
|
resume/artifacts/autotune.json
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"selected": {
|
| 3 |
+
"microbatch": 8,
|
| 4 |
+
"grad_accum": 3,
|
| 5 |
+
"compile": true,
|
| 6 |
+
"compile_mode": "default",
|
| 7 |
+
"tokens_per_sec": 89445.99334863275,
|
| 8 |
+
"average_tokens_per_sec": 89444.8633550159,
|
| 9 |
+
"p10_tokens_per_sec": 89344.54672252262,
|
| 10 |
+
"p90_tokens_per_sec": 89528.96203402826,
|
| 11 |
+
"average_step_seconds": 0.549523363999615,
|
| 12 |
+
"measured_steps": 50,
|
| 13 |
+
"peak_gib": 6.564574718475342,
|
| 14 |
+
"attention_backend": "cudnn"
|
| 15 |
+
},
|
| 16 |
+
"best_eager": {
|
| 17 |
+
"microbatch": 6,
|
| 18 |
+
"grad_accum": 4,
|
| 19 |
+
"compile": false,
|
| 20 |
+
"compile_mode": null,
|
| 21 |
+
"tokens_per_sec": 72779.22098370155,
|
| 22 |
+
"average_tokens_per_sec": 72686.84173544499,
|
| 23 |
+
"p10_tokens_per_sec": 72594.40211376193,
|
| 24 |
+
"p90_tokens_per_sec": 73023.81311474911,
|
| 25 |
+
"average_step_seconds": 0.676274363998964,
|
| 26 |
+
"measured_steps": 50,
|
| 27 |
+
"peak_gib": 5.965656280517578,
|
| 28 |
+
"attention_backend": "cudnn"
|
| 29 |
+
},
|
| 30 |
+
"results": [
|
| 31 |
+
{
|
| 32 |
+
"microbatch": 5,
|
| 33 |
+
"grad_accum": 3,
|
| 34 |
+
"compile": false,
|
| 35 |
+
"compile_mode": null,
|
| 36 |
+
"tokens_per_sec": 69142.84797054232,
|
| 37 |
+
"average_tokens_per_sec": 68942.92490092275,
|
| 38 |
+
"p10_tokens_per_sec": 68404.52458687228,
|
| 39 |
+
"p90_tokens_per_sec": 69558.42851403252,
|
| 40 |
+
"average_step_seconds": 0.44562956400041004,
|
| 41 |
+
"measured_steps": 50,
|
| 42 |
+
"peak_gib": 5.198768615722656,
|
| 43 |
+
"attention_backend": "cudnn"
|
| 44 |
+
},
|
| 45 |
+
{
|
| 46 |
+
"microbatch": 5,
|
| 47 |
+
"grad_accum": 3,
|
| 48 |
+
"compile": true,
|
| 49 |
+
"compile_mode": "default",
|
| 50 |
+
"tokens_per_sec": 84537.06633037937,
|
| 51 |
+
"average_tokens_per_sec": 84528.41417894745,
|
| 52 |
+
"p10_tokens_per_sec": 84212.90403651971,
|
| 53 |
+
"p90_tokens_per_sec": 84809.25922724494,
|
| 54 |
+
"average_step_seconds": 0.36343143600126493,
|
| 55 |
+
"measured_steps": 50,
|
| 56 |
+
"peak_gib": 4.5903239250183105,
|
| 57 |
+
"attention_backend": "cudnn"
|
| 58 |
+
},
|
| 59 |
+
{
|
| 60 |
+
"microbatch": 6,
|
| 61 |
+
"grad_accum": 3,
|
| 62 |
+
"compile": false,
|
| 63 |
+
"compile_mode": null,
|
| 64 |
+
"tokens_per_sec": 69358.98911499346,
|
| 65 |
+
"average_tokens_per_sec": 69211.02001694769,
|
| 66 |
+
"p10_tokens_per_sec": 68395.45277013684,
|
| 67 |
+
"p90_tokens_per_sec": 69775.53680685474,
|
| 68 |
+
"average_step_seconds": 0.5326724359992658,
|
| 69 |
+
"measured_steps": 50,
|
| 70 |
+
"peak_gib": 5.9600982666015625,
|
| 71 |
+
"attention_backend": "cudnn"
|
| 72 |
+
},
|
| 73 |
+
{
|
| 74 |
+
"microbatch": 6,
|
| 75 |
+
"grad_accum": 3,
|
| 76 |
+
"compile": true,
|
| 77 |
+
"compile_mode": "default",
|
| 78 |
+
"tokens_per_sec": 85005.56070311155,
|
| 79 |
+
"average_tokens_per_sec": 85016.33866867538,
|
| 80 |
+
"p10_tokens_per_sec": 83462.51714754912,
|
| 81 |
+
"p90_tokens_per_sec": 85675.79853778225,
|
| 82 |
+
"average_step_seconds": 0.4337354880009661,
|
| 83 |
+
"measured_steps": 50,
|
| 84 |
+
"peak_gib": 5.266883373260498,
|
| 85 |
+
"attention_backend": "cudnn"
|
| 86 |
+
},
|
| 87 |
+
{
|
| 88 |
+
"microbatch": 6,
|
| 89 |
+
"grad_accum": 4,
|
| 90 |
+
"compile": false,
|
| 91 |
+
"compile_mode": null,
|
| 92 |
+
"tokens_per_sec": 72779.22098370155,
|
| 93 |
+
"average_tokens_per_sec": 72686.84173544499,
|
| 94 |
+
"p10_tokens_per_sec": 72594.40211376193,
|
| 95 |
+
"p90_tokens_per_sec": 73023.81311474911,
|
| 96 |
+
"average_step_seconds": 0.676274363998964,
|
| 97 |
+
"measured_steps": 50,
|
| 98 |
+
"peak_gib": 5.965656280517578,
|
| 99 |
+
"attention_backend": "cudnn"
|
| 100 |
+
},
|
| 101 |
+
{
|
| 102 |
+
"microbatch": 6,
|
| 103 |
+
"grad_accum": 4,
|
| 104 |
+
"compile": true,
|
| 105 |
+
"compile_mode": "default",
|
| 106 |
+
"tokens_per_sec": 88941.710905432,
|
| 107 |
+
"average_tokens_per_sec": 88941.84349428031,
|
| 108 |
+
"p10_tokens_per_sec": 88846.51904815416,
|
| 109 |
+
"p90_tokens_per_sec": 89047.07563353243,
|
| 110 |
+
"average_step_seconds": 0.5526312520014471,
|
| 111 |
+
"measured_steps": 50,
|
| 112 |
+
"peak_gib": 5.266921520233154,
|
| 113 |
+
"attention_backend": "cudnn"
|
| 114 |
+
},
|
| 115 |
+
{
|
| 116 |
+
"microbatch": 8,
|
| 117 |
+
"grad_accum": 2,
|
| 118 |
+
"compile": false,
|
| 119 |
+
"compile_mode": null,
|
| 120 |
+
"tokens_per_sec": 71432.95470939987,
|
| 121 |
+
"average_tokens_per_sec": 71244.80450390381,
|
| 122 |
+
"p10_tokens_per_sec": 71215.24486226412,
|
| 123 |
+
"p90_tokens_per_sec": 71553.3818194886,
|
| 124 |
+
"average_step_seconds": 0.45999654399842255,
|
| 125 |
+
"measured_steps": 50,
|
| 126 |
+
"peak_gib": 7.537319183349609,
|
| 127 |
+
"attention_backend": "cudnn"
|
| 128 |
+
},
|
| 129 |
+
{
|
| 130 |
+
"microbatch": 8,
|
| 131 |
+
"grad_accum": 2,
|
| 132 |
+
"compile": true,
|
| 133 |
+
"compile_mode": "default",
|
| 134 |
+
"tokens_per_sec": 89210.10479908106,
|
| 135 |
+
"average_tokens_per_sec": 88917.94627874688,
|
| 136 |
+
"p10_tokens_per_sec": 89043.76861913929,
|
| 137 |
+
"p90_tokens_per_sec": 89375.04023150704,
|
| 138 |
+
"average_step_seconds": 0.36858677200070816,
|
| 139 |
+
"measured_steps": 50,
|
| 140 |
+
"peak_gib": 6.563186168670654,
|
| 141 |
+
"attention_backend": "cudnn"
|
| 142 |
+
},
|
| 143 |
+
{
|
| 144 |
+
"microbatch": 8,
|
| 145 |
+
"grad_accum": 3,
|
| 146 |
+
"compile": false,
|
| 147 |
+
"compile_mode": null,
|
| 148 |
+
"tokens_per_sec": 71752.63949365195,
|
| 149 |
+
"average_tokens_per_sec": 71738.85536654401,
|
| 150 |
+
"p10_tokens_per_sec": 71578.61932457695,
|
| 151 |
+
"p90_tokens_per_sec": 71862.33870713774,
|
| 152 |
+
"average_step_seconds": 0.6851534099999117,
|
| 153 |
+
"measured_steps": 50,
|
| 154 |
+
"peak_gib": 7.536571502685547,
|
| 155 |
+
"attention_backend": "cudnn"
|
| 156 |
+
},
|
| 157 |
+
{
|
| 158 |
+
"microbatch": 8,
|
| 159 |
+
"grad_accum": 3,
|
| 160 |
+
"compile": true,
|
| 161 |
+
"compile_mode": "default",
|
| 162 |
+
"tokens_per_sec": 89445.99334863275,
|
| 163 |
+
"average_tokens_per_sec": 89444.8633550159,
|
| 164 |
+
"p10_tokens_per_sec": 89344.54672252262,
|
| 165 |
+
"p90_tokens_per_sec": 89528.96203402826,
|
| 166 |
+
"average_step_seconds": 0.549523363999615,
|
| 167 |
+
"measured_steps": 50,
|
| 168 |
+
"peak_gib": 6.564574718475342,
|
| 169 |
+
"attention_backend": "cudnn"
|
| 170 |
+
},
|
| 171 |
+
{
|
| 172 |
+
"microbatch": 10,
|
| 173 |
+
"grad_accum": 2,
|
| 174 |
+
"compile": false,
|
| 175 |
+
"compile_mode": null,
|
| 176 |
+
"tokens_per_sec": 69852.45715698763,
|
| 177 |
+
"average_tokens_per_sec": 69719.44084914621,
|
| 178 |
+
"p10_tokens_per_sec": 69724.38271446126,
|
| 179 |
+
"p90_tokens_per_sec": 69995.07846979078,
|
| 180 |
+
"average_step_seconds": 0.5875548560012248,
|
| 181 |
+
"measured_steps": 50,
|
| 182 |
+
"peak_gib": 9.104179382324219,
|
| 183 |
+
"attention_backend": "cudnn"
|
| 184 |
+
},
|
| 185 |
+
{
|
| 186 |
+
"microbatch": 10,
|
| 187 |
+
"grad_accum": 2,
|
| 188 |
+
"compile": true,
|
| 189 |
+
"compile_mode": "default",
|
| 190 |
+
"tokens_per_sec": 89042.88786929363,
|
| 191 |
+
"average_tokens_per_sec": 88826.54532414334,
|
| 192 |
+
"p10_tokens_per_sec": 88921.57837423113,
|
| 193 |
+
"p90_tokens_per_sec": 89187.438419859,
|
| 194 |
+
"average_step_seconds": 0.46118442999955733,
|
| 195 |
+
"measured_steps": 50,
|
| 196 |
+
"peak_gib": 7.920142650604248,
|
| 197 |
+
"attention_backend": "cudnn"
|
| 198 |
+
},
|
| 199 |
+
{
|
| 200 |
+
"microbatch": 12,
|
| 201 |
+
"grad_accum": 2,
|
| 202 |
+
"compile": false,
|
| 203 |
+
"compile_mode": null,
|
| 204 |
+
"tokens_per_sec": 17407.417292769976,
|
| 205 |
+
"average_tokens_per_sec": 16870.67263639786,
|
| 206 |
+
"p10_tokens_per_sec": 5742.86275913661,
|
| 207 |
+
"p90_tokens_per_sec": 31079.470988878318,
|
| 208 |
+
"average_step_seconds": 3.9928920720002496,
|
| 209 |
+
"measured_steps": 50,
|
| 210 |
+
"peak_gib": 10.677471160888672,
|
| 211 |
+
"attention_backend": "cudnn"
|
| 212 |
+
},
|
| 213 |
+
{
|
| 214 |
+
"microbatch": 12,
|
| 215 |
+
"grad_accum": 2,
|
| 216 |
+
"compile": true,
|
| 217 |
+
"compile_mode": "default",
|
| 218 |
+
"tokens_per_sec": 89207.88471267493,
|
| 219 |
+
"average_tokens_per_sec": 89040.59748015198,
|
| 220 |
+
"p10_tokens_per_sec": 89041.46192278565,
|
| 221 |
+
"p90_tokens_per_sec": 89522.86346394477,
|
| 222 |
+
"average_step_seconds": 0.552097511999018,
|
| 223 |
+
"measured_steps": 50,
|
| 224 |
+
"peak_gib": 9.247085094451904,
|
| 225 |
+
"attention_backend": "cudnn"
|
| 226 |
+
}
|
| 227 |
+
],
|
| 228 |
+
"minimum_compile_gain": 0.03
|
| 229 |
+
}
|
resume/artifacts/tokenizer/chat_template.jinja
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{%- for message in messages %}
|
| 2 |
+
{%- if message['role'] not in ['system', 'developer', 'user', 'assistant', 'tool', 'function', 'observation'] %}
|
| 3 |
+
{{- raise_exception('Unsupported QyrouArch chat role: ' + message['role']) }}
|
| 4 |
+
{%- endif %}
|
| 5 |
+
{{- '<|im_start|><|' + message['role'] + '|>\n' + message['content'] + '<|im_end|>\n' }}
|
| 6 |
+
{%- endfor %}
|
| 7 |
+
{%- if add_generation_prompt %}
|
| 8 |
+
{{- '<|im_start|><|assistant|>\n' }}
|
| 9 |
+
{%- endif %}
|
| 10 |
+
|
resume/artifacts/tokenizer/marker_manifest.json
ADDED
|
@@ -0,0 +1,1190 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"id": 0,
|
| 4 |
+
"token": "<|bos|>",
|
| 5 |
+
"special": true,
|
| 6 |
+
"category": "core"
|
| 7 |
+
},
|
| 8 |
+
{
|
| 9 |
+
"id": 1,
|
| 10 |
+
"token": "<|eos|>",
|
| 11 |
+
"special": true,
|
| 12 |
+
"category": "core"
|
| 13 |
+
},
|
| 14 |
+
{
|
| 15 |
+
"id": 2,
|
| 16 |
+
"token": "<|pad|>",
|
| 17 |
+
"special": true,
|
| 18 |
+
"category": "core"
|
| 19 |
+
},
|
| 20 |
+
{
|
| 21 |
+
"id": 3,
|
| 22 |
+
"token": "<|unk|>",
|
| 23 |
+
"special": true,
|
| 24 |
+
"category": "core"
|
| 25 |
+
},
|
| 26 |
+
{
|
| 27 |
+
"id": 4,
|
| 28 |
+
"token": "<|eod|>",
|
| 29 |
+
"special": true,
|
| 30 |
+
"category": "core"
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"id": 5,
|
| 34 |
+
"token": "<|startoftext|>",
|
| 35 |
+
"special": true,
|
| 36 |
+
"category": "text_boundaries"
|
| 37 |
+
},
|
| 38 |
+
{
|
| 39 |
+
"id": 6,
|
| 40 |
+
"token": "<|endoftext|>",
|
| 41 |
+
"special": true,
|
| 42 |
+
"category": "text_boundaries"
|
| 43 |
+
},
|
| 44 |
+
{
|
| 45 |
+
"id": 7,
|
| 46 |
+
"token": "<|endofprompt|>",
|
| 47 |
+
"special": true,
|
| 48 |
+
"category": "text_boundaries"
|
| 49 |
+
},
|
| 50 |
+
{
|
| 51 |
+
"id": 8,
|
| 52 |
+
"token": "<|im_start|>",
|
| 53 |
+
"special": true,
|
| 54 |
+
"category": "chatml"
|
| 55 |
+
},
|
| 56 |
+
{
|
| 57 |
+
"id": 9,
|
| 58 |
+
"token": "<|im_end|>",
|
| 59 |
+
"special": true,
|
| 60 |
+
"category": "chatml"
|
| 61 |
+
},
|
| 62 |
+
{
|
| 63 |
+
"id": 10,
|
| 64 |
+
"token": "<|system|>",
|
| 65 |
+
"special": true,
|
| 66 |
+
"category": "chatml"
|
| 67 |
+
},
|
| 68 |
+
{
|
| 69 |
+
"id": 11,
|
| 70 |
+
"token": "<|developer|>",
|
| 71 |
+
"special": true,
|
| 72 |
+
"category": "chatml"
|
| 73 |
+
},
|
| 74 |
+
{
|
| 75 |
+
"id": 12,
|
| 76 |
+
"token": "<|user|>",
|
| 77 |
+
"special": true,
|
| 78 |
+
"category": "chatml"
|
| 79 |
+
},
|
| 80 |
+
{
|
| 81 |
+
"id": 13,
|
| 82 |
+
"token": "<|assistant|>",
|
| 83 |
+
"special": true,
|
| 84 |
+
"category": "chatml"
|
| 85 |
+
},
|
| 86 |
+
{
|
| 87 |
+
"id": 14,
|
| 88 |
+
"token": "<|tool|>",
|
| 89 |
+
"special": true,
|
| 90 |
+
"category": "chatml"
|
| 91 |
+
},
|
| 92 |
+
{
|
| 93 |
+
"id": 15,
|
| 94 |
+
"token": "<|function|>",
|
| 95 |
+
"special": true,
|
| 96 |
+
"category": "chatml"
|
| 97 |
+
},
|
| 98 |
+
{
|
| 99 |
+
"id": 16,
|
| 100 |
+
"token": "<|observation|>",
|
| 101 |
+
"special": true,
|
| 102 |
+
"category": "chatml"
|
| 103 |
+
},
|
| 104 |
+
{
|
| 105 |
+
"id": 17,
|
| 106 |
+
"token": "<|eot|>",
|
| 107 |
+
"special": true,
|
| 108 |
+
"category": "chatml"
|
| 109 |
+
},
|
| 110 |
+
{
|
| 111 |
+
"id": 18,
|
| 112 |
+
"token": "<think>",
|
| 113 |
+
"special": false,
|
| 114 |
+
"category": "reasoning"
|
| 115 |
+
},
|
| 116 |
+
{
|
| 117 |
+
"id": 19,
|
| 118 |
+
"token": "</think>",
|
| 119 |
+
"special": false,
|
| 120 |
+
"category": "reasoning"
|
| 121 |
+
},
|
| 122 |
+
{
|
| 123 |
+
"id": 20,
|
| 124 |
+
"token": "<analysis>",
|
| 125 |
+
"special": false,
|
| 126 |
+
"category": "reasoning"
|
| 127 |
+
},
|
| 128 |
+
{
|
| 129 |
+
"id": 21,
|
| 130 |
+
"token": "</analysis>",
|
| 131 |
+
"special": false,
|
| 132 |
+
"category": "reasoning"
|
| 133 |
+
},
|
| 134 |
+
{
|
| 135 |
+
"id": 22,
|
| 136 |
+
"token": "<reasoning>",
|
| 137 |
+
"special": false,
|
| 138 |
+
"category": "reasoning"
|
| 139 |
+
},
|
| 140 |
+
{
|
| 141 |
+
"id": 23,
|
| 142 |
+
"token": "</reasoning>",
|
| 143 |
+
"special": false,
|
| 144 |
+
"category": "reasoning"
|
| 145 |
+
},
|
| 146 |
+
{
|
| 147 |
+
"id": 24,
|
| 148 |
+
"token": "<commentary>",
|
| 149 |
+
"special": false,
|
| 150 |
+
"category": "reasoning"
|
| 151 |
+
},
|
| 152 |
+
{
|
| 153 |
+
"id": 25,
|
| 154 |
+
"token": "</commentary>",
|
| 155 |
+
"special": false,
|
| 156 |
+
"category": "reasoning"
|
| 157 |
+
},
|
| 158 |
+
{
|
| 159 |
+
"id": 26,
|
| 160 |
+
"token": "<final>",
|
| 161 |
+
"special": false,
|
| 162 |
+
"category": "reasoning"
|
| 163 |
+
},
|
| 164 |
+
{
|
| 165 |
+
"id": 27,
|
| 166 |
+
"token": "</final>",
|
| 167 |
+
"special": false,
|
| 168 |
+
"category": "reasoning"
|
| 169 |
+
},
|
| 170 |
+
{
|
| 171 |
+
"id": 28,
|
| 172 |
+
"token": "<tools>",
|
| 173 |
+
"special": false,
|
| 174 |
+
"category": "tools"
|
| 175 |
+
},
|
| 176 |
+
{
|
| 177 |
+
"id": 29,
|
| 178 |
+
"token": "</tools>",
|
| 179 |
+
"special": false,
|
| 180 |
+
"category": "tools"
|
| 181 |
+
},
|
| 182 |
+
{
|
| 183 |
+
"id": 30,
|
| 184 |
+
"token": "<available_tools>",
|
| 185 |
+
"special": false,
|
| 186 |
+
"category": "tools"
|
| 187 |
+
},
|
| 188 |
+
{
|
| 189 |
+
"id": 31,
|
| 190 |
+
"token": "</available_tools>",
|
| 191 |
+
"special": false,
|
| 192 |
+
"category": "tools"
|
| 193 |
+
},
|
| 194 |
+
{
|
| 195 |
+
"id": 32,
|
| 196 |
+
"token": "<tool_call>",
|
| 197 |
+
"special": false,
|
| 198 |
+
"category": "tools"
|
| 199 |
+
},
|
| 200 |
+
{
|
| 201 |
+
"id": 33,
|
| 202 |
+
"token": "</tool_call>",
|
| 203 |
+
"special": false,
|
| 204 |
+
"category": "tools"
|
| 205 |
+
},
|
| 206 |
+
{
|
| 207 |
+
"id": 34,
|
| 208 |
+
"token": "<tool_response>",
|
| 209 |
+
"special": false,
|
| 210 |
+
"category": "tools"
|
| 211 |
+
},
|
| 212 |
+
{
|
| 213 |
+
"id": 35,
|
| 214 |
+
"token": "</tool_response>",
|
| 215 |
+
"special": false,
|
| 216 |
+
"category": "tools"
|
| 217 |
+
},
|
| 218 |
+
{
|
| 219 |
+
"id": 36,
|
| 220 |
+
"token": "<function_call>",
|
| 221 |
+
"special": false,
|
| 222 |
+
"category": "tools"
|
| 223 |
+
},
|
| 224 |
+
{
|
| 225 |
+
"id": 37,
|
| 226 |
+
"token": "</function_call>",
|
| 227 |
+
"special": false,
|
| 228 |
+
"category": "tools"
|
| 229 |
+
},
|
| 230 |
+
{
|
| 231 |
+
"id": 38,
|
| 232 |
+
"token": "<function_response>",
|
| 233 |
+
"special": false,
|
| 234 |
+
"category": "tools"
|
| 235 |
+
},
|
| 236 |
+
{
|
| 237 |
+
"id": 39,
|
| 238 |
+
"token": "</function_response>",
|
| 239 |
+
"special": false,
|
| 240 |
+
"category": "tools"
|
| 241 |
+
},
|
| 242 |
+
{
|
| 243 |
+
"id": 40,
|
| 244 |
+
"token": "<|tool_sep|>",
|
| 245 |
+
"special": false,
|
| 246 |
+
"category": "tools"
|
| 247 |
+
},
|
| 248 |
+
{
|
| 249 |
+
"id": 41,
|
| 250 |
+
"token": "<|fim_prefix|>",
|
| 251 |
+
"special": false,
|
| 252 |
+
"category": "qwen_fim"
|
| 253 |
+
},
|
| 254 |
+
{
|
| 255 |
+
"id": 42,
|
| 256 |
+
"token": "<|fim_middle|>",
|
| 257 |
+
"special": false,
|
| 258 |
+
"category": "qwen_fim"
|
| 259 |
+
},
|
| 260 |
+
{
|
| 261 |
+
"id": 43,
|
| 262 |
+
"token": "<|fim_suffix|>",
|
| 263 |
+
"special": false,
|
| 264 |
+
"category": "qwen_fim"
|
| 265 |
+
},
|
| 266 |
+
{
|
| 267 |
+
"id": 44,
|
| 268 |
+
"token": "<|fim_pad|>",
|
| 269 |
+
"special": false,
|
| 270 |
+
"category": "qwen_fim"
|
| 271 |
+
},
|
| 272 |
+
{
|
| 273 |
+
"id": 45,
|
| 274 |
+
"token": "<|repo_name|>",
|
| 275 |
+
"special": false,
|
| 276 |
+
"category": "qwen_fim"
|
| 277 |
+
},
|
| 278 |
+
{
|
| 279 |
+
"id": 46,
|
| 280 |
+
"token": "<|file_sep|>",
|
| 281 |
+
"special": false,
|
| 282 |
+
"category": "qwen_fim"
|
| 283 |
+
},
|
| 284 |
+
{
|
| 285 |
+
"id": 47,
|
| 286 |
+
"token": "<fim_prefix>",
|
| 287 |
+
"special": false,
|
| 288 |
+
"category": "starcoder"
|
| 289 |
+
},
|
| 290 |
+
{
|
| 291 |
+
"id": 48,
|
| 292 |
+
"token": "<fim_middle>",
|
| 293 |
+
"special": false,
|
| 294 |
+
"category": "starcoder"
|
| 295 |
+
},
|
| 296 |
+
{
|
| 297 |
+
"id": 49,
|
| 298 |
+
"token": "<fim_suffix>",
|
| 299 |
+
"special": false,
|
| 300 |
+
"category": "starcoder"
|
| 301 |
+
},
|
| 302 |
+
{
|
| 303 |
+
"id": 50,
|
| 304 |
+
"token": "<fim_pad>",
|
| 305 |
+
"special": false,
|
| 306 |
+
"category": "starcoder"
|
| 307 |
+
},
|
| 308 |
+
{
|
| 309 |
+
"id": 51,
|
| 310 |
+
"token": "<repo_name>",
|
| 311 |
+
"special": false,
|
| 312 |
+
"category": "starcoder"
|
| 313 |
+
},
|
| 314 |
+
{
|
| 315 |
+
"id": 52,
|
| 316 |
+
"token": "<file_sep>",
|
| 317 |
+
"special": false,
|
| 318 |
+
"category": "starcoder"
|
| 319 |
+
},
|
| 320 |
+
{
|
| 321 |
+
"id": 53,
|
| 322 |
+
"token": "<issue_start>",
|
| 323 |
+
"special": false,
|
| 324 |
+
"category": "starcoder"
|
| 325 |
+
},
|
| 326 |
+
{
|
| 327 |
+
"id": 54,
|
| 328 |
+
"token": "<issue_comment>",
|
| 329 |
+
"special": false,
|
| 330 |
+
"category": "starcoder"
|
| 331 |
+
},
|
| 332 |
+
{
|
| 333 |
+
"id": 55,
|
| 334 |
+
"token": "<issue_closed>",
|
| 335 |
+
"special": false,
|
| 336 |
+
"category": "starcoder"
|
| 337 |
+
},
|
| 338 |
+
{
|
| 339 |
+
"id": 56,
|
| 340 |
+
"token": "<jupyter_start>",
|
| 341 |
+
"special": false,
|
| 342 |
+
"category": "starcoder"
|
| 343 |
+
},
|
| 344 |
+
{
|
| 345 |
+
"id": 57,
|
| 346 |
+
"token": "<jupyter_text>",
|
| 347 |
+
"special": false,
|
| 348 |
+
"category": "starcoder"
|
| 349 |
+
},
|
| 350 |
+
{
|
| 351 |
+
"id": 58,
|
| 352 |
+
"token": "<jupyter_code>",
|
| 353 |
+
"special": false,
|
| 354 |
+
"category": "starcoder"
|
| 355 |
+
},
|
| 356 |
+
{
|
| 357 |
+
"id": 59,
|
| 358 |
+
"token": "<jupyter_output>",
|
| 359 |
+
"special": false,
|
| 360 |
+
"category": "starcoder"
|
| 361 |
+
},
|
| 362 |
+
{
|
| 363 |
+
"id": 60,
|
| 364 |
+
"token": "<jupyter_script>",
|
| 365 |
+
"special": false,
|
| 366 |
+
"category": "starcoder"
|
| 367 |
+
},
|
| 368 |
+
{
|
| 369 |
+
"id": 61,
|
| 370 |
+
"token": "<empty_output>",
|
| 371 |
+
"special": false,
|
| 372 |
+
"category": "starcoder"
|
| 373 |
+
},
|
| 374 |
+
{
|
| 375 |
+
"id": 62,
|
| 376 |
+
"token": "<|begin_of_text|>",
|
| 377 |
+
"special": true,
|
| 378 |
+
"category": "llama"
|
| 379 |
+
},
|
| 380 |
+
{
|
| 381 |
+
"id": 63,
|
| 382 |
+
"token": "<|end_of_text|>",
|
| 383 |
+
"special": true,
|
| 384 |
+
"category": "llama"
|
| 385 |
+
},
|
| 386 |
+
{
|
| 387 |
+
"id": 64,
|
| 388 |
+
"token": "<|start_header_id|>",
|
| 389 |
+
"special": true,
|
| 390 |
+
"category": "llama"
|
| 391 |
+
},
|
| 392 |
+
{
|
| 393 |
+
"id": 65,
|
| 394 |
+
"token": "<|end_header_id|>",
|
| 395 |
+
"special": true,
|
| 396 |
+
"category": "llama"
|
| 397 |
+
},
|
| 398 |
+
{
|
| 399 |
+
"id": 66,
|
| 400 |
+
"token": "<|eot_id|>",
|
| 401 |
+
"special": true,
|
| 402 |
+
"category": "llama"
|
| 403 |
+
},
|
| 404 |
+
{
|
| 405 |
+
"id": 67,
|
| 406 |
+
"token": "<|eom_id|>",
|
| 407 |
+
"special": true,
|
| 408 |
+
"category": "llama"
|
| 409 |
+
},
|
| 410 |
+
{
|
| 411 |
+
"id": 68,
|
| 412 |
+
"token": "<|python_tag|>",
|
| 413 |
+
"special": true,
|
| 414 |
+
"category": "llama"
|
| 415 |
+
},
|
| 416 |
+
{
|
| 417 |
+
"id": 69,
|
| 418 |
+
"token": "<start_of_turn>",
|
| 419 |
+
"special": true,
|
| 420 |
+
"category": "gemma"
|
| 421 |
+
},
|
| 422 |
+
{
|
| 423 |
+
"id": 70,
|
| 424 |
+
"token": "<end_of_turn>",
|
| 425 |
+
"special": true,
|
| 426 |
+
"category": "gemma"
|
| 427 |
+
},
|
| 428 |
+
{
|
| 429 |
+
"id": 71,
|
| 430 |
+
"token": "<start_of_image>",
|
| 431 |
+
"special": true,
|
| 432 |
+
"category": "gemma"
|
| 433 |
+
},
|
| 434 |
+
{
|
| 435 |
+
"id": 72,
|
| 436 |
+
"token": "<s>",
|
| 437 |
+
"special": true,
|
| 438 |
+
"category": "mistral"
|
| 439 |
+
},
|
| 440 |
+
{
|
| 441 |
+
"id": 73,
|
| 442 |
+
"token": "</s>",
|
| 443 |
+
"special": true,
|
| 444 |
+
"category": "mistral"
|
| 445 |
+
},
|
| 446 |
+
{
|
| 447 |
+
"id": 74,
|
| 448 |
+
"token": "<unk>",
|
| 449 |
+
"special": true,
|
| 450 |
+
"category": "mistral"
|
| 451 |
+
},
|
| 452 |
+
{
|
| 453 |
+
"id": 75,
|
| 454 |
+
"token": "<pad>",
|
| 455 |
+
"special": true,
|
| 456 |
+
"category": "mistral"
|
| 457 |
+
},
|
| 458 |
+
{
|
| 459 |
+
"id": 76,
|
| 460 |
+
"token": "[INST]",
|
| 461 |
+
"special": true,
|
| 462 |
+
"category": "mistral"
|
| 463 |
+
},
|
| 464 |
+
{
|
| 465 |
+
"id": 77,
|
| 466 |
+
"token": "[/INST]",
|
| 467 |
+
"special": true,
|
| 468 |
+
"category": "mistral"
|
| 469 |
+
},
|
| 470 |
+
{
|
| 471 |
+
"id": 78,
|
| 472 |
+
"token": "[AVAILABLE_TOOLS]",
|
| 473 |
+
"special": true,
|
| 474 |
+
"category": "mistral"
|
| 475 |
+
},
|
| 476 |
+
{
|
| 477 |
+
"id": 79,
|
| 478 |
+
"token": "[/AVAILABLE_TOOLS]",
|
| 479 |
+
"special": true,
|
| 480 |
+
"category": "mistral"
|
| 481 |
+
},
|
| 482 |
+
{
|
| 483 |
+
"id": 80,
|
| 484 |
+
"token": "[TOOL_CALLS]",
|
| 485 |
+
"special": true,
|
| 486 |
+
"category": "mistral"
|
| 487 |
+
},
|
| 488 |
+
{
|
| 489 |
+
"id": 81,
|
| 490 |
+
"token": "[TOOL_RESULTS]",
|
| 491 |
+
"special": true,
|
| 492 |
+
"category": "mistral"
|
| 493 |
+
},
|
| 494 |
+
{
|
| 495 |
+
"id": 82,
|
| 496 |
+
"token": "[/TOOL_RESULTS]",
|
| 497 |
+
"special": true,
|
| 498 |
+
"category": "mistral"
|
| 499 |
+
},
|
| 500 |
+
{
|
| 501 |
+
"id": 83,
|
| 502 |
+
"token": "[SYSTEM_PROMPT]",
|
| 503 |
+
"special": true,
|
| 504 |
+
"category": "mistral"
|
| 505 |
+
},
|
| 506 |
+
{
|
| 507 |
+
"id": 84,
|
| 508 |
+
"token": "[/SYSTEM_PROMPT]",
|
| 509 |
+
"special": true,
|
| 510 |
+
"category": "mistral"
|
| 511 |
+
},
|
| 512 |
+
{
|
| 513 |
+
"id": 85,
|
| 514 |
+
"token": "[TOOL_CONTENT]",
|
| 515 |
+
"special": true,
|
| 516 |
+
"category": "mistral"
|
| 517 |
+
},
|
| 518 |
+
{
|
| 519 |
+
"id": 86,
|
| 520 |
+
"token": "[ARGS]",
|
| 521 |
+
"special": true,
|
| 522 |
+
"category": "mistral"
|
| 523 |
+
},
|
| 524 |
+
{
|
| 525 |
+
"id": 87,
|
| 526 |
+
"token": "[CALL_ID]",
|
| 527 |
+
"special": true,
|
| 528 |
+
"category": "mistral"
|
| 529 |
+
},
|
| 530 |
+
{
|
| 531 |
+
"id": 88,
|
| 532 |
+
"token": "[PREFIX]",
|
| 533 |
+
"special": true,
|
| 534 |
+
"category": "mistral"
|
| 535 |
+
},
|
| 536 |
+
{
|
| 537 |
+
"id": 89,
|
| 538 |
+
"token": "[MIDDLE]",
|
| 539 |
+
"special": true,
|
| 540 |
+
"category": "mistral"
|
| 541 |
+
},
|
| 542 |
+
{
|
| 543 |
+
"id": 90,
|
| 544 |
+
"token": "[SUFFIX]",
|
| 545 |
+
"special": true,
|
| 546 |
+
"category": "mistral"
|
| 547 |
+
},
|
| 548 |
+
{
|
| 549 |
+
"id": 91,
|
| 550 |
+
"token": "[THINK]",
|
| 551 |
+
"special": true,
|
| 552 |
+
"category": "mistral"
|
| 553 |
+
},
|
| 554 |
+
{
|
| 555 |
+
"id": 92,
|
| 556 |
+
"token": "[/THINK]",
|
| 557 |
+
"special": true,
|
| 558 |
+
"category": "mistral"
|
| 559 |
+
},
|
| 560 |
+
{
|
| 561 |
+
"id": 93,
|
| 562 |
+
"token": "[MODEL_SETTINGS]",
|
| 563 |
+
"special": true,
|
| 564 |
+
"category": "mistral"
|
| 565 |
+
},
|
| 566 |
+
{
|
| 567 |
+
"id": 94,
|
| 568 |
+
"token": "[/MODEL_SETTINGS]",
|
| 569 |
+
"special": true,
|
| 570 |
+
"category": "mistral"
|
| 571 |
+
},
|
| 572 |
+
{
|
| 573 |
+
"id": 95,
|
| 574 |
+
"token": "<|begin▁of▁sentence|>",
|
| 575 |
+
"special": true,
|
| 576 |
+
"category": "deepseek"
|
| 577 |
+
},
|
| 578 |
+
{
|
| 579 |
+
"id": 96,
|
| 580 |
+
"token": "<|end▁of▁sentence|>",
|
| 581 |
+
"special": true,
|
| 582 |
+
"category": "deepseek"
|
| 583 |
+
},
|
| 584 |
+
{
|
| 585 |
+
"id": 97,
|
| 586 |
+
"token": "<|User|>",
|
| 587 |
+
"special": true,
|
| 588 |
+
"category": "deepseek"
|
| 589 |
+
},
|
| 590 |
+
{
|
| 591 |
+
"id": 98,
|
| 592 |
+
"token": "<|Assistant|>",
|
| 593 |
+
"special": true,
|
| 594 |
+
"category": "deepseek"
|
| 595 |
+
},
|
| 596 |
+
{
|
| 597 |
+
"id": 99,
|
| 598 |
+
"token": "<|tool▁calls▁begin|>",
|
| 599 |
+
"special": true,
|
| 600 |
+
"category": "deepseek"
|
| 601 |
+
},
|
| 602 |
+
{
|
| 603 |
+
"id": 100,
|
| 604 |
+
"token": "<|tool▁call▁begin|>",
|
| 605 |
+
"special": true,
|
| 606 |
+
"category": "deepseek"
|
| 607 |
+
},
|
| 608 |
+
{
|
| 609 |
+
"id": 101,
|
| 610 |
+
"token": "<|tool▁sep|>",
|
| 611 |
+
"special": true,
|
| 612 |
+
"category": "deepseek"
|
| 613 |
+
},
|
| 614 |
+
{
|
| 615 |
+
"id": 102,
|
| 616 |
+
"token": "<|tool▁call▁end|>",
|
| 617 |
+
"special": true,
|
| 618 |
+
"category": "deepseek"
|
| 619 |
+
},
|
| 620 |
+
{
|
| 621 |
+
"id": 103,
|
| 622 |
+
"token": "<|tool▁calls▁end|>",
|
| 623 |
+
"special": true,
|
| 624 |
+
"category": "deepseek"
|
| 625 |
+
},
|
| 626 |
+
{
|
| 627 |
+
"id": 104,
|
| 628 |
+
"token": "<|tool▁outputs▁begin|>",
|
| 629 |
+
"special": true,
|
| 630 |
+
"category": "deepseek"
|
| 631 |
+
},
|
| 632 |
+
{
|
| 633 |
+
"id": 105,
|
| 634 |
+
"token": "<|tool▁output▁begin|>",
|
| 635 |
+
"special": true,
|
| 636 |
+
"category": "deepseek"
|
| 637 |
+
},
|
| 638 |
+
{
|
| 639 |
+
"id": 106,
|
| 640 |
+
"token": "<|tool▁output▁end|>",
|
| 641 |
+
"special": true,
|
| 642 |
+
"category": "deepseek"
|
| 643 |
+
},
|
| 644 |
+
{
|
| 645 |
+
"id": 107,
|
| 646 |
+
"token": "<|tool▁outputs▁end|>",
|
| 647 |
+
"special": true,
|
| 648 |
+
"category": "deepseek"
|
| 649 |
+
},
|
| 650 |
+
{
|
| 651 |
+
"id": 108,
|
| 652 |
+
"token": "<|fim▁begin|>",
|
| 653 |
+
"special": true,
|
| 654 |
+
"category": "deepseek"
|
| 655 |
+
},
|
| 656 |
+
{
|
| 657 |
+
"id": 109,
|
| 658 |
+
"token": "<|fim▁hole|>",
|
| 659 |
+
"special": true,
|
| 660 |
+
"category": "deepseek"
|
| 661 |
+
},
|
| 662 |
+
{
|
| 663 |
+
"id": 110,
|
| 664 |
+
"token": "<|fim▁end|>",
|
| 665 |
+
"special": true,
|
| 666 |
+
"category": "deepseek"
|
| 667 |
+
},
|
| 668 |
+
{
|
| 669 |
+
"id": 111,
|
| 670 |
+
"token": "<|start|>",
|
| 671 |
+
"special": true,
|
| 672 |
+
"category": "harmony"
|
| 673 |
+
},
|
| 674 |
+
{
|
| 675 |
+
"id": 112,
|
| 676 |
+
"token": "<|end|>",
|
| 677 |
+
"special": true,
|
| 678 |
+
"category": "harmony"
|
| 679 |
+
},
|
| 680 |
+
{
|
| 681 |
+
"id": 113,
|
| 682 |
+
"token": "<|message|>",
|
| 683 |
+
"special": true,
|
| 684 |
+
"category": "harmony"
|
| 685 |
+
},
|
| 686 |
+
{
|
| 687 |
+
"id": 114,
|
| 688 |
+
"token": "<|channel|>",
|
| 689 |
+
"special": true,
|
| 690 |
+
"category": "harmony"
|
| 691 |
+
},
|
| 692 |
+
{
|
| 693 |
+
"id": 115,
|
| 694 |
+
"token": "<|constrain|>",
|
| 695 |
+
"special": true,
|
| 696 |
+
"category": "harmony"
|
| 697 |
+
},
|
| 698 |
+
{
|
| 699 |
+
"id": 116,
|
| 700 |
+
"token": "<|return|>",
|
| 701 |
+
"special": true,
|
| 702 |
+
"category": "harmony"
|
| 703 |
+
},
|
| 704 |
+
{
|
| 705 |
+
"id": 117,
|
| 706 |
+
"token": "<|call|>",
|
| 707 |
+
"special": true,
|
| 708 |
+
"category": "harmony"
|
| 709 |
+
},
|
| 710 |
+
{
|
| 711 |
+
"id": 118,
|
| 712 |
+
"token": "<|vision_start|>",
|
| 713 |
+
"special": true,
|
| 714 |
+
"category": "vision"
|
| 715 |
+
},
|
| 716 |
+
{
|
| 717 |
+
"id": 119,
|
| 718 |
+
"token": "<|vision_end|>",
|
| 719 |
+
"special": true,
|
| 720 |
+
"category": "vision"
|
| 721 |
+
},
|
| 722 |
+
{
|
| 723 |
+
"id": 120,
|
| 724 |
+
"token": "<|vision_pad|>",
|
| 725 |
+
"special": true,
|
| 726 |
+
"category": "vision"
|
| 727 |
+
},
|
| 728 |
+
{
|
| 729 |
+
"id": 121,
|
| 730 |
+
"token": "<|image_pad|>",
|
| 731 |
+
"special": true,
|
| 732 |
+
"category": "vision"
|
| 733 |
+
},
|
| 734 |
+
{
|
| 735 |
+
"id": 122,
|
| 736 |
+
"token": "<|video_pad|>",
|
| 737 |
+
"special": true,
|
| 738 |
+
"category": "vision"
|
| 739 |
+
},
|
| 740 |
+
{
|
| 741 |
+
"id": 123,
|
| 742 |
+
"token": "<|image|>",
|
| 743 |
+
"special": true,
|
| 744 |
+
"category": "vision"
|
| 745 |
+
},
|
| 746 |
+
{
|
| 747 |
+
"id": 124,
|
| 748 |
+
"token": "<|video|>",
|
| 749 |
+
"special": true,
|
| 750 |
+
"category": "vision"
|
| 751 |
+
},
|
| 752 |
+
{
|
| 753 |
+
"id": 125,
|
| 754 |
+
"token": "[IMG]",
|
| 755 |
+
"special": true,
|
| 756 |
+
"category": "vision"
|
| 757 |
+
},
|
| 758 |
+
{
|
| 759 |
+
"id": 126,
|
| 760 |
+
"token": "[IMG_BREAK]",
|
| 761 |
+
"special": true,
|
| 762 |
+
"category": "vision"
|
| 763 |
+
},
|
| 764 |
+
{
|
| 765 |
+
"id": 127,
|
| 766 |
+
"token": "[IMG_END]",
|
| 767 |
+
"special": true,
|
| 768 |
+
"category": "vision"
|
| 769 |
+
},
|
| 770 |
+
{
|
| 771 |
+
"id": 128,
|
| 772 |
+
"token": "<|audio_bos|>",
|
| 773 |
+
"special": true,
|
| 774 |
+
"category": "audio"
|
| 775 |
+
},
|
| 776 |
+
{
|
| 777 |
+
"id": 129,
|
| 778 |
+
"token": "<|AUDIO|>",
|
| 779 |
+
"special": true,
|
| 780 |
+
"category": "audio"
|
| 781 |
+
},
|
| 782 |
+
{
|
| 783 |
+
"id": 130,
|
| 784 |
+
"token": "<|audio_eos|>",
|
| 785 |
+
"special": true,
|
| 786 |
+
"category": "audio"
|
| 787 |
+
},
|
| 788 |
+
{
|
| 789 |
+
"id": 131,
|
| 790 |
+
"token": "<|audio_pad|>",
|
| 791 |
+
"special": true,
|
| 792 |
+
"category": "audio"
|
| 793 |
+
},
|
| 794 |
+
{
|
| 795 |
+
"id": 132,
|
| 796 |
+
"token": "[AUDIO]",
|
| 797 |
+
"special": true,
|
| 798 |
+
"category": "audio"
|
| 799 |
+
},
|
| 800 |
+
{
|
| 801 |
+
"id": 133,
|
| 802 |
+
"token": "[BEGIN_AUDIO]",
|
| 803 |
+
"special": true,
|
| 804 |
+
"category": "audio"
|
| 805 |
+
},
|
| 806 |
+
{
|
| 807 |
+
"id": 134,
|
| 808 |
+
"token": "<|reserved_000|>",
|
| 809 |
+
"special": true,
|
| 810 |
+
"category": "reserved"
|
| 811 |
+
},
|
| 812 |
+
{
|
| 813 |
+
"id": 135,
|
| 814 |
+
"token": "<|reserved_001|>",
|
| 815 |
+
"special": true,
|
| 816 |
+
"category": "reserved"
|
| 817 |
+
},
|
| 818 |
+
{
|
| 819 |
+
"id": 136,
|
| 820 |
+
"token": "<|reserved_002|>",
|
| 821 |
+
"special": true,
|
| 822 |
+
"category": "reserved"
|
| 823 |
+
},
|
| 824 |
+
{
|
| 825 |
+
"id": 137,
|
| 826 |
+
"token": "<|reserved_003|>",
|
| 827 |
+
"special": true,
|
| 828 |
+
"category": "reserved"
|
| 829 |
+
},
|
| 830 |
+
{
|
| 831 |
+
"id": 138,
|
| 832 |
+
"token": "<|reserved_004|>",
|
| 833 |
+
"special": true,
|
| 834 |
+
"category": "reserved"
|
| 835 |
+
},
|
| 836 |
+
{
|
| 837 |
+
"id": 139,
|
| 838 |
+
"token": "<|reserved_005|>",
|
| 839 |
+
"special": true,
|
| 840 |
+
"category": "reserved"
|
| 841 |
+
},
|
| 842 |
+
{
|
| 843 |
+
"id": 140,
|
| 844 |
+
"token": "<|reserved_006|>",
|
| 845 |
+
"special": true,
|
| 846 |
+
"category": "reserved"
|
| 847 |
+
},
|
| 848 |
+
{
|
| 849 |
+
"id": 141,
|
| 850 |
+
"token": "<|reserved_007|>",
|
| 851 |
+
"special": true,
|
| 852 |
+
"category": "reserved"
|
| 853 |
+
},
|
| 854 |
+
{
|
| 855 |
+
"id": 142,
|
| 856 |
+
"token": "<|reserved_008|>",
|
| 857 |
+
"special": true,
|
| 858 |
+
"category": "reserved"
|
| 859 |
+
},
|
| 860 |
+
{
|
| 861 |
+
"id": 143,
|
| 862 |
+
"token": "<|reserved_009|>",
|
| 863 |
+
"special": true,
|
| 864 |
+
"category": "reserved"
|
| 865 |
+
},
|
| 866 |
+
{
|
| 867 |
+
"id": 144,
|
| 868 |
+
"token": "<|reserved_010|>",
|
| 869 |
+
"special": true,
|
| 870 |
+
"category": "reserved"
|
| 871 |
+
},
|
| 872 |
+
{
|
| 873 |
+
"id": 145,
|
| 874 |
+
"token": "<|reserved_011|>",
|
| 875 |
+
"special": true,
|
| 876 |
+
"category": "reserved"
|
| 877 |
+
},
|
| 878 |
+
{
|
| 879 |
+
"id": 146,
|
| 880 |
+
"token": "<|reserved_012|>",
|
| 881 |
+
"special": true,
|
| 882 |
+
"category": "reserved"
|
| 883 |
+
},
|
| 884 |
+
{
|
| 885 |
+
"id": 147,
|
| 886 |
+
"token": "<|reserved_013|>",
|
| 887 |
+
"special": true,
|
| 888 |
+
"category": "reserved"
|
| 889 |
+
},
|
| 890 |
+
{
|
| 891 |
+
"id": 148,
|
| 892 |
+
"token": "<|reserved_014|>",
|
| 893 |
+
"special": true,
|
| 894 |
+
"category": "reserved"
|
| 895 |
+
},
|
| 896 |
+
{
|
| 897 |
+
"id": 149,
|
| 898 |
+
"token": "<|reserved_015|>",
|
| 899 |
+
"special": true,
|
| 900 |
+
"category": "reserved"
|
| 901 |
+
},
|
| 902 |
+
{
|
| 903 |
+
"id": 150,
|
| 904 |
+
"token": "<|reserved_016|>",
|
| 905 |
+
"special": true,
|
| 906 |
+
"category": "reserved"
|
| 907 |
+
},
|
| 908 |
+
{
|
| 909 |
+
"id": 151,
|
| 910 |
+
"token": "<|reserved_017|>",
|
| 911 |
+
"special": true,
|
| 912 |
+
"category": "reserved"
|
| 913 |
+
},
|
| 914 |
+
{
|
| 915 |
+
"id": 152,
|
| 916 |
+
"token": "<|reserved_018|>",
|
| 917 |
+
"special": true,
|
| 918 |
+
"category": "reserved"
|
| 919 |
+
},
|
| 920 |
+
{
|
| 921 |
+
"id": 153,
|
| 922 |
+
"token": "<|reserved_019|>",
|
| 923 |
+
"special": true,
|
| 924 |
+
"category": "reserved"
|
| 925 |
+
},
|
| 926 |
+
{
|
| 927 |
+
"id": 154,
|
| 928 |
+
"token": "<|reserved_020|>",
|
| 929 |
+
"special": true,
|
| 930 |
+
"category": "reserved"
|
| 931 |
+
},
|
| 932 |
+
{
|
| 933 |
+
"id": 155,
|
| 934 |
+
"token": "<|reserved_021|>",
|
| 935 |
+
"special": true,
|
| 936 |
+
"category": "reserved"
|
| 937 |
+
},
|
| 938 |
+
{
|
| 939 |
+
"id": 156,
|
| 940 |
+
"token": "<|reserved_022|>",
|
| 941 |
+
"special": true,
|
| 942 |
+
"category": "reserved"
|
| 943 |
+
},
|
| 944 |
+
{
|
| 945 |
+
"id": 157,
|
| 946 |
+
"token": "<|reserved_023|>",
|
| 947 |
+
"special": true,
|
| 948 |
+
"category": "reserved"
|
| 949 |
+
},
|
| 950 |
+
{
|
| 951 |
+
"id": 158,
|
| 952 |
+
"token": "<|reserved_024|>",
|
| 953 |
+
"special": true,
|
| 954 |
+
"category": "reserved"
|
| 955 |
+
},
|
| 956 |
+
{
|
| 957 |
+
"id": 159,
|
| 958 |
+
"token": "<|reserved_025|>",
|
| 959 |
+
"special": true,
|
| 960 |
+
"category": "reserved"
|
| 961 |
+
},
|
| 962 |
+
{
|
| 963 |
+
"id": 160,
|
| 964 |
+
"token": "<|reserved_026|>",
|
| 965 |
+
"special": true,
|
| 966 |
+
"category": "reserved"
|
| 967 |
+
},
|
| 968 |
+
{
|
| 969 |
+
"id": 161,
|
| 970 |
+
"token": "<|reserved_027|>",
|
| 971 |
+
"special": true,
|
| 972 |
+
"category": "reserved"
|
| 973 |
+
},
|
| 974 |
+
{
|
| 975 |
+
"id": 162,
|
| 976 |
+
"token": "<|reserved_028|>",
|
| 977 |
+
"special": true,
|
| 978 |
+
"category": "reserved"
|
| 979 |
+
},
|
| 980 |
+
{
|
| 981 |
+
"id": 163,
|
| 982 |
+
"token": "<|reserved_029|>",
|
| 983 |
+
"special": true,
|
| 984 |
+
"category": "reserved"
|
| 985 |
+
},
|
| 986 |
+
{
|
| 987 |
+
"id": 164,
|
| 988 |
+
"token": "<|reserved_030|>",
|
| 989 |
+
"special": true,
|
| 990 |
+
"category": "reserved"
|
| 991 |
+
},
|
| 992 |
+
{
|
| 993 |
+
"id": 165,
|
| 994 |
+
"token": "<|reserved_031|>",
|
| 995 |
+
"special": true,
|
| 996 |
+
"category": "reserved"
|
| 997 |
+
},
|
| 998 |
+
{
|
| 999 |
+
"id": 166,
|
| 1000 |
+
"token": "<|reserved_032|>",
|
| 1001 |
+
"special": true,
|
| 1002 |
+
"category": "reserved"
|
| 1003 |
+
},
|
| 1004 |
+
{
|
| 1005 |
+
"id": 167,
|
| 1006 |
+
"token": "<|reserved_033|>",
|
| 1007 |
+
"special": true,
|
| 1008 |
+
"category": "reserved"
|
| 1009 |
+
},
|
| 1010 |
+
{
|
| 1011 |
+
"id": 168,
|
| 1012 |
+
"token": "<|reserved_034|>",
|
| 1013 |
+
"special": true,
|
| 1014 |
+
"category": "reserved"
|
| 1015 |
+
},
|
| 1016 |
+
{
|
| 1017 |
+
"id": 169,
|
| 1018 |
+
"token": "<|reserved_035|>",
|
| 1019 |
+
"special": true,
|
| 1020 |
+
"category": "reserved"
|
| 1021 |
+
},
|
| 1022 |
+
{
|
| 1023 |
+
"id": 170,
|
| 1024 |
+
"token": "<|reserved_036|>",
|
| 1025 |
+
"special": true,
|
| 1026 |
+
"category": "reserved"
|
| 1027 |
+
},
|
| 1028 |
+
{
|
| 1029 |
+
"id": 171,
|
| 1030 |
+
"token": "<|reserved_037|>",
|
| 1031 |
+
"special": true,
|
| 1032 |
+
"category": "reserved"
|
| 1033 |
+
},
|
| 1034 |
+
{
|
| 1035 |
+
"id": 172,
|
| 1036 |
+
"token": "<|reserved_038|>",
|
| 1037 |
+
"special": true,
|
| 1038 |
+
"category": "reserved"
|
| 1039 |
+
},
|
| 1040 |
+
{
|
| 1041 |
+
"id": 173,
|
| 1042 |
+
"token": "<|reserved_039|>",
|
| 1043 |
+
"special": true,
|
| 1044 |
+
"category": "reserved"
|
| 1045 |
+
},
|
| 1046 |
+
{
|
| 1047 |
+
"id": 174,
|
| 1048 |
+
"token": "<|reserved_040|>",
|
| 1049 |
+
"special": true,
|
| 1050 |
+
"category": "reserved"
|
| 1051 |
+
},
|
| 1052 |
+
{
|
| 1053 |
+
"id": 175,
|
| 1054 |
+
"token": "<|reserved_041|>",
|
| 1055 |
+
"special": true,
|
| 1056 |
+
"category": "reserved"
|
| 1057 |
+
},
|
| 1058 |
+
{
|
| 1059 |
+
"id": 176,
|
| 1060 |
+
"token": "<|reserved_042|>",
|
| 1061 |
+
"special": true,
|
| 1062 |
+
"category": "reserved"
|
| 1063 |
+
},
|
| 1064 |
+
{
|
| 1065 |
+
"id": 177,
|
| 1066 |
+
"token": "<|reserved_043|>",
|
| 1067 |
+
"special": true,
|
| 1068 |
+
"category": "reserved"
|
| 1069 |
+
},
|
| 1070 |
+
{
|
| 1071 |
+
"id": 178,
|
| 1072 |
+
"token": "<|reserved_044|>",
|
| 1073 |
+
"special": true,
|
| 1074 |
+
"category": "reserved"
|
| 1075 |
+
},
|
| 1076 |
+
{
|
| 1077 |
+
"id": 179,
|
| 1078 |
+
"token": "<|reserved_045|>",
|
| 1079 |
+
"special": true,
|
| 1080 |
+
"category": "reserved"
|
| 1081 |
+
},
|
| 1082 |
+
{
|
| 1083 |
+
"id": 180,
|
| 1084 |
+
"token": "<|reserved_046|>",
|
| 1085 |
+
"special": true,
|
| 1086 |
+
"category": "reserved"
|
| 1087 |
+
},
|
| 1088 |
+
{
|
| 1089 |
+
"id": 181,
|
| 1090 |
+
"token": "<|reserved_047|>",
|
| 1091 |
+
"special": true,
|
| 1092 |
+
"category": "reserved"
|
| 1093 |
+
},
|
| 1094 |
+
{
|
| 1095 |
+
"id": 182,
|
| 1096 |
+
"token": "<|reserved_048|>",
|
| 1097 |
+
"special": true,
|
| 1098 |
+
"category": "reserved"
|
| 1099 |
+
},
|
| 1100 |
+
{
|
| 1101 |
+
"id": 183,
|
| 1102 |
+
"token": "<|reserved_049|>",
|
| 1103 |
+
"special": true,
|
| 1104 |
+
"category": "reserved"
|
| 1105 |
+
},
|
| 1106 |
+
{
|
| 1107 |
+
"id": 184,
|
| 1108 |
+
"token": "<|reserved_050|>",
|
| 1109 |
+
"special": true,
|
| 1110 |
+
"category": "reserved"
|
| 1111 |
+
},
|
| 1112 |
+
{
|
| 1113 |
+
"id": 185,
|
| 1114 |
+
"token": "<|reserved_051|>",
|
| 1115 |
+
"special": true,
|
| 1116 |
+
"category": "reserved"
|
| 1117 |
+
},
|
| 1118 |
+
{
|
| 1119 |
+
"id": 186,
|
| 1120 |
+
"token": "<|reserved_052|>",
|
| 1121 |
+
"special": true,
|
| 1122 |
+
"category": "reserved"
|
| 1123 |
+
},
|
| 1124 |
+
{
|
| 1125 |
+
"id": 187,
|
| 1126 |
+
"token": "<|reserved_053|>",
|
| 1127 |
+
"special": true,
|
| 1128 |
+
"category": "reserved"
|
| 1129 |
+
},
|
| 1130 |
+
{
|
| 1131 |
+
"id": 188,
|
| 1132 |
+
"token": "<|reserved_054|>",
|
| 1133 |
+
"special": true,
|
| 1134 |
+
"category": "reserved"
|
| 1135 |
+
},
|
| 1136 |
+
{
|
| 1137 |
+
"id": 189,
|
| 1138 |
+
"token": "<|reserved_055|>",
|
| 1139 |
+
"special": true,
|
| 1140 |
+
"category": "reserved"
|
| 1141 |
+
},
|
| 1142 |
+
{
|
| 1143 |
+
"id": 190,
|
| 1144 |
+
"token": "<|reserved_056|>",
|
| 1145 |
+
"special": true,
|
| 1146 |
+
"category": "reserved"
|
| 1147 |
+
},
|
| 1148 |
+
{
|
| 1149 |
+
"id": 191,
|
| 1150 |
+
"token": "<|reserved_057|>",
|
| 1151 |
+
"special": true,
|
| 1152 |
+
"category": "reserved"
|
| 1153 |
+
},
|
| 1154 |
+
{
|
| 1155 |
+
"id": 192,
|
| 1156 |
+
"token": "<|reserved_058|>",
|
| 1157 |
+
"special": true,
|
| 1158 |
+
"category": "reserved"
|
| 1159 |
+
},
|
| 1160 |
+
{
|
| 1161 |
+
"id": 193,
|
| 1162 |
+
"token": "<|reserved_059|>",
|
| 1163 |
+
"special": true,
|
| 1164 |
+
"category": "reserved"
|
| 1165 |
+
},
|
| 1166 |
+
{
|
| 1167 |
+
"id": 194,
|
| 1168 |
+
"token": "<|reserved_060|>",
|
| 1169 |
+
"special": true,
|
| 1170 |
+
"category": "reserved"
|
| 1171 |
+
},
|
| 1172 |
+
{
|
| 1173 |
+
"id": 195,
|
| 1174 |
+
"token": "<|reserved_061|>",
|
| 1175 |
+
"special": true,
|
| 1176 |
+
"category": "reserved"
|
| 1177 |
+
},
|
| 1178 |
+
{
|
| 1179 |
+
"id": 196,
|
| 1180 |
+
"token": "<|reserved_062|>",
|
| 1181 |
+
"special": true,
|
| 1182 |
+
"category": "reserved"
|
| 1183 |
+
},
|
| 1184 |
+
{
|
| 1185 |
+
"id": 197,
|
| 1186 |
+
"token": "<|reserved_063|>",
|
| 1187 |
+
"special": true,
|
| 1188 |
+
"category": "reserved"
|
| 1189 |
+
}
|
| 1190 |
+
]
|
resume/artifacts/tokenizer/special_tokens_map.json
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"bos_token": "<|bos|>",
|
| 3 |
+
"eos_token": "<|eos|>",
|
| 4 |
+
"pad_token": "<|pad|>",
|
| 5 |
+
"unk_token": "<|unk|>",
|
| 6 |
+
"additional_special_tokens": [
|
| 7 |
+
"<|eod|>",
|
| 8 |
+
"<|startoftext|>",
|
| 9 |
+
"<|endoftext|>",
|
| 10 |
+
"<|endofprompt|>",
|
| 11 |
+
"<|im_start|>",
|
| 12 |
+
"<|im_end|>",
|
| 13 |
+
"<|system|>",
|
| 14 |
+
"<|developer|>",
|
| 15 |
+
"<|user|>",
|
| 16 |
+
"<|assistant|>",
|
| 17 |
+
"<|tool|>",
|
| 18 |
+
"<|function|>",
|
| 19 |
+
"<|observation|>",
|
| 20 |
+
"<|eot|>",
|
| 21 |
+
"<|begin_of_text|>",
|
| 22 |
+
"<|end_of_text|>",
|
| 23 |
+
"<|start_header_id|>",
|
| 24 |
+
"<|end_header_id|>",
|
| 25 |
+
"<|eot_id|>",
|
| 26 |
+
"<|eom_id|>",
|
| 27 |
+
"<|python_tag|>",
|
| 28 |
+
"<start_of_turn>",
|
| 29 |
+
"<end_of_turn>",
|
| 30 |
+
"<start_of_image>",
|
| 31 |
+
"<s>",
|
| 32 |
+
"</s>",
|
| 33 |
+
"<unk>",
|
| 34 |
+
"<pad>",
|
| 35 |
+
"[INST]",
|
| 36 |
+
"[/INST]",
|
| 37 |
+
"[AVAILABLE_TOOLS]",
|
| 38 |
+
"[/AVAILABLE_TOOLS]",
|
| 39 |
+
"[TOOL_CALLS]",
|
| 40 |
+
"[TOOL_RESULTS]",
|
| 41 |
+
"[/TOOL_RESULTS]",
|
| 42 |
+
"[SYSTEM_PROMPT]",
|
| 43 |
+
"[/SYSTEM_PROMPT]",
|
| 44 |
+
"[TOOL_CONTENT]",
|
| 45 |
+
"[ARGS]",
|
| 46 |
+
"[CALL_ID]",
|
| 47 |
+
"[PREFIX]",
|
| 48 |
+
"[MIDDLE]",
|
| 49 |
+
"[SUFFIX]",
|
| 50 |
+
"[THINK]",
|
| 51 |
+
"[/THINK]",
|
| 52 |
+
"[MODEL_SETTINGS]",
|
| 53 |
+
"[/MODEL_SETTINGS]",
|
| 54 |
+
"<|begin▁of▁sentence|>",
|
| 55 |
+
"<|end▁of▁sentence|>",
|
| 56 |
+
"<|User|>",
|
| 57 |
+
"<|Assistant|>",
|
| 58 |
+
"<|tool▁calls▁begin|>",
|
| 59 |
+
"<|tool▁call▁begin|>",
|
| 60 |
+
"<|tool▁sep|>",
|
| 61 |
+
"<|tool▁call▁end|>",
|
| 62 |
+
"<|tool▁calls▁end|>",
|
| 63 |
+
"<|tool▁outputs▁begin|>",
|
| 64 |
+
"<|tool▁output▁begin|>",
|
| 65 |
+
"<|tool▁output▁end|>",
|
| 66 |
+
"<|tool▁outputs▁end|>",
|
| 67 |
+
"<|fim▁begin|>",
|
| 68 |
+
"<|fim▁hole|>",
|
| 69 |
+
"<|fim▁end|>",
|
| 70 |
+
"<|start|>",
|
| 71 |
+
"<|end|>",
|
| 72 |
+
"<|message|>",
|
| 73 |
+
"<|channel|>",
|
| 74 |
+
"<|constrain|>",
|
| 75 |
+
"<|return|>",
|
| 76 |
+
"<|call|>",
|
| 77 |
+
"<|vision_start|>",
|
| 78 |
+
"<|vision_end|>",
|
| 79 |
+
"<|vision_pad|>",
|
| 80 |
+
"<|image_pad|>",
|
| 81 |
+
"<|video_pad|>",
|
| 82 |
+
"<|image|>",
|
| 83 |
+
"<|video|>",
|
| 84 |
+
"[IMG]",
|
| 85 |
+
"[IMG_BREAK]",
|
| 86 |
+
"[IMG_END]",
|
| 87 |
+
"<|audio_bos|>",
|
| 88 |
+
"<|AUDIO|>",
|
| 89 |
+
"<|audio_eos|>",
|
| 90 |
+
"<|audio_pad|>",
|
| 91 |
+
"[AUDIO]",
|
| 92 |
+
"[BEGIN_AUDIO]",
|
| 93 |
+
"<|reserved_000|>",
|
| 94 |
+
"<|reserved_001|>",
|
| 95 |
+
"<|reserved_002|>",
|
| 96 |
+
"<|reserved_003|>",
|
| 97 |
+
"<|reserved_004|>",
|
| 98 |
+
"<|reserved_005|>",
|
| 99 |
+
"<|reserved_006|>",
|
| 100 |
+
"<|reserved_007|>",
|
| 101 |
+
"<|reserved_008|>",
|
| 102 |
+
"<|reserved_009|>",
|
| 103 |
+
"<|reserved_010|>",
|
| 104 |
+
"<|reserved_011|>",
|
| 105 |
+
"<|reserved_012|>",
|
| 106 |
+
"<|reserved_013|>",
|
| 107 |
+
"<|reserved_014|>",
|
| 108 |
+
"<|reserved_015|>",
|
| 109 |
+
"<|reserved_016|>",
|
| 110 |
+
"<|reserved_017|>",
|
| 111 |
+
"<|reserved_018|>",
|
| 112 |
+
"<|reserved_019|>",
|
| 113 |
+
"<|reserved_020|>",
|
| 114 |
+
"<|reserved_021|>",
|
| 115 |
+
"<|reserved_022|>",
|
| 116 |
+
"<|reserved_023|>",
|
| 117 |
+
"<|reserved_024|>",
|
| 118 |
+
"<|reserved_025|>",
|
| 119 |
+
"<|reserved_026|>",
|
| 120 |
+
"<|reserved_027|>",
|
| 121 |
+
"<|reserved_028|>",
|
| 122 |
+
"<|reserved_029|>",
|
| 123 |
+
"<|reserved_030|>",
|
| 124 |
+
"<|reserved_031|>",
|
| 125 |
+
"<|reserved_032|>",
|
| 126 |
+
"<|reserved_033|>",
|
| 127 |
+
"<|reserved_034|>",
|
| 128 |
+
"<|reserved_035|>",
|
| 129 |
+
"<|reserved_036|>",
|
| 130 |
+
"<|reserved_037|>",
|
| 131 |
+
"<|reserved_038|>",
|
| 132 |
+
"<|reserved_039|>",
|
| 133 |
+
"<|reserved_040|>",
|
| 134 |
+
"<|reserved_041|>",
|
| 135 |
+
"<|reserved_042|>",
|
| 136 |
+
"<|reserved_043|>",
|
| 137 |
+
"<|reserved_044|>",
|
| 138 |
+
"<|reserved_045|>",
|
| 139 |
+
"<|reserved_046|>",
|
| 140 |
+
"<|reserved_047|>",
|
| 141 |
+
"<|reserved_048|>",
|
| 142 |
+
"<|reserved_049|>",
|
| 143 |
+
"<|reserved_050|>",
|
| 144 |
+
"<|reserved_051|>",
|
| 145 |
+
"<|reserved_052|>",
|
| 146 |
+
"<|reserved_053|>",
|
| 147 |
+
"<|reserved_054|>",
|
| 148 |
+
"<|reserved_055|>",
|
| 149 |
+
"<|reserved_056|>",
|
| 150 |
+
"<|reserved_057|>",
|
| 151 |
+
"<|reserved_058|>",
|
| 152 |
+
"<|reserved_059|>",
|
| 153 |
+
"<|reserved_060|>",
|
| 154 |
+
"<|reserved_061|>",
|
| 155 |
+
"<|reserved_062|>",
|
| 156 |
+
"<|reserved_063|>"
|
| 157 |
+
]
|
| 158 |
+
}
|
resume/artifacts/tokenizer/tokenizer.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
resume/artifacts/tokenizer/tokenizer_config.json
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"tokenizer_class": "PreTrainedTokenizerFast",
|
| 3 |
+
"model_max_length": 2048,
|
| 4 |
+
"bos_token": "<|bos|>",
|
| 5 |
+
"eos_token": "<|eos|>",
|
| 6 |
+
"pad_token": "<|pad|>",
|
| 7 |
+
"unk_token": "<|unk|>",
|
| 8 |
+
"chat_template": "{%- for message in messages %}\n{%- if message['role'] not in ['system', 'developer', 'user', 'assistant', 'tool', 'function', 'observation'] %}\n{{- raise_exception('Unsupported QyrouArch chat role: ' + message['role']) }}\n{%- endif %}\n{{- '<|im_start|><|' + message['role'] + '|>\\n' + message['content'] + '<|im_end|>\\n' }}\n{%- endfor %}\n{%- if add_generation_prompt %}\n{{- '<|im_start|><|assistant|>\\n' }}\n{%- endif %}\n\n",
|
| 9 |
+
"clean_up_tokenization_spaces": false
|
| 10 |
+
}
|
resume/artifacts/tokenizer/tokenizer_quality.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"rows": 20000,
|
| 3 |
+
"bytes": 50676351,
|
| 4 |
+
"tokens": 12913545,
|
| 5 |
+
"bytes_per_token": 3.924278809575527,
|
| 6 |
+
"unknown_tokens": 0,
|
| 7 |
+
"long_fragment_rate": 2.0133898166614976e-06,
|
| 8 |
+
"vocab_size": 20000,
|
| 9 |
+
"requested_markers": 134,
|
| 10 |
+
"reserved_markers": 64,
|
| 11 |
+
"sample_rows": 6236030,
|
| 12 |
+
"sample_bytes": 19870811666,
|
| 13 |
+
"sample_sha256": "d16839542054d09d28b257f7afd3bee0ae849fec257e239e3a6792884d76acc1",
|
| 14 |
+
"corpus_manifest_sha256": "0a52b66efc4668646b373241610fb03af13807e785685a501bfc92c7bb87c6b0",
|
| 15 |
+
"tokenizer_sha256": "5b14f71c0e1d5a628c440067db4cd75d1aa855e6c34b4dd577a2412031e82ca7"
|
| 16 |
+
}
|
resume/checkpoints/qyrou-1-exp-base/checkpoint-step-000680000/manifest.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"version": 1,
|
| 3 |
+
"step": 680000,
|
| 4 |
+
"total_tokens": 33423360000,
|
| 5 |
+
"validation_loss": null,
|
| 6 |
+
"created_at": 1785466854.7029169,
|
| 7 |
+
"files": [
|
| 8 |
+
{
|
| 9 |
+
"path": "model\\cache.py",
|
| 10 |
+
"bytes": 3950,
|
| 11 |
+
"sha256": "14e55f9639c155b728ab887c48729547345c8dac6b38da5ecdceb8f71d309977"
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"path": "model\\config.json",
|
| 15 |
+
"bytes": 1123,
|
| 16 |
+
"sha256": "6f7818cab6cdd79ec29b0cae53e54937d4250721c31194027ef10bcbf066ba2d"
|
| 17 |
+
},
|
| 18 |
+
{
|
| 19 |
+
"path": "model\\configuration_qyrou_arch.py",
|
| 20 |
+
"bytes": 3162,
|
| 21 |
+
"sha256": "b20e96120f16c73505e6bb714965d25115182c09cf2972979e9e26b18228df9d"
|
| 22 |
+
},
|
| 23 |
+
{
|
| 24 |
+
"path": "model\\generation_config.json",
|
| 25 |
+
"bytes": 226,
|
| 26 |
+
"sha256": "2a0b4fdc827622535d629dc7bee72e376b7962aa1198ed9b6ba04b5ea62b7182"
|
| 27 |
+
},
|
| 28 |
+
{
|
| 29 |
+
"path": "model\\model.safetensors",
|
| 30 |
+
"bytes": 261234016,
|
| 31 |
+
"sha256": "15e793a9c28db4f2c843a4369363170c619ac1c73fdc4e1c98ffef5a9ca07f23"
|
| 32 |
+
},
|
| 33 |
+
{
|
| 34 |
+
"path": "model\\modeling_qyrou_arch.py",
|
| 35 |
+
"bytes": 20438,
|
| 36 |
+
"sha256": "9834518c57aaf605e18cc1a927f5b5a30915f6bcec000e59286ab5c1ab1e67bd"
|
| 37 |
+
},
|
| 38 |
+
{
|
| 39 |
+
"path": "model\\triton_kernels.py",
|
| 40 |
+
"bytes": 3996,
|
| 41 |
+
"sha256": "b57566f7acfd30180dfd2388c1f4a9bafd6bf43f83a38706a7aacce58c54b985"
|
| 42 |
+
},
|
| 43 |
+
{
|
| 44 |
+
"path": "training_state.pt",
|
| 45 |
+
"bytes": 526781105,
|
| 46 |
+
"sha256": "06ed8c306ade8342a16f73be3c4eb327bc1ce1f88900a772e3f4731872870031"
|
| 47 |
+
}
|
| 48 |
+
]
|
| 49 |
+
}
|
resume/checkpoints/qyrou-1-exp-base/checkpoint-step-000680000/model/cache.py
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from dataclasses import dataclass, field
|
| 4 |
+
from typing import Any
|
| 5 |
+
|
| 6 |
+
import torch
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
@dataclass
|
| 10 |
+
class QyrouArchHybridCache:
|
| 11 |
+
"""Attention K/V plus short-convolution state for incremental decoding."""
|
| 12 |
+
|
| 13 |
+
num_layers: int
|
| 14 |
+
max_cache_len: int | None = None
|
| 15 |
+
attention: list[tuple[torch.Tensor, torch.Tensor] | None] = field(init=False)
|
| 16 |
+
convolution: list[torch.Tensor | None] = field(init=False)
|
| 17 |
+
seen_tokens: int = 0
|
| 18 |
+
|
| 19 |
+
def __post_init__(self) -> None:
|
| 20 |
+
self.attention = [None] * self.num_layers
|
| 21 |
+
self.convolution = [None] * self.num_layers
|
| 22 |
+
if self.max_cache_len is not None and self.max_cache_len <= 0:
|
| 23 |
+
raise ValueError("max_cache_len must be positive")
|
| 24 |
+
|
| 25 |
+
@property
|
| 26 |
+
def is_static(self) -> bool:
|
| 27 |
+
return self.max_cache_len is not None
|
| 28 |
+
|
| 29 |
+
def get_seq_length(self, _layer_idx: int = 0) -> int:
|
| 30 |
+
return self.seen_tokens
|
| 31 |
+
|
| 32 |
+
def get_max_cache_shape(self) -> int | None:
|
| 33 |
+
return self.max_cache_len
|
| 34 |
+
|
| 35 |
+
def update_attention(
|
| 36 |
+
self,
|
| 37 |
+
layer_idx: int,
|
| 38 |
+
key: torch.Tensor,
|
| 39 |
+
value: torch.Tensor,
|
| 40 |
+
cache_position: torch.Tensor,
|
| 41 |
+
) -> tuple[torch.Tensor, torch.Tensor]:
|
| 42 |
+
if key.ndim != 4 or key.shape != value.shape:
|
| 43 |
+
raise ValueError("K/V cache tensors must have identical [batch, heads, seq, dim] shapes")
|
| 44 |
+
if self.is_static:
|
| 45 |
+
assert self.max_cache_len is not None
|
| 46 |
+
if int(cache_position.max()) >= self.max_cache_len:
|
| 47 |
+
raise ValueError("Static cache capacity exceeded")
|
| 48 |
+
existing = self.attention[layer_idx]
|
| 49 |
+
if existing is None:
|
| 50 |
+
shape = (*key.shape[:2], self.max_cache_len, key.shape[-1])
|
| 51 |
+
key_cache = torch.zeros(shape, dtype=key.dtype, device=key.device)
|
| 52 |
+
value_cache = torch.zeros(shape, dtype=value.dtype, device=value.device)
|
| 53 |
+
else:
|
| 54 |
+
key_cache, value_cache = existing
|
| 55 |
+
key_cache.index_copy_(2, cache_position, key)
|
| 56 |
+
value_cache.index_copy_(2, cache_position, value)
|
| 57 |
+
self.attention[layer_idx] = (key_cache, value_cache)
|
| 58 |
+
visible = max(self.seen_tokens, int(cache_position.max()) + 1)
|
| 59 |
+
return key_cache[:, :, :visible], value_cache[:, :, :visible]
|
| 60 |
+
existing = self.attention[layer_idx]
|
| 61 |
+
if existing is not None:
|
| 62 |
+
key = torch.cat((existing[0], key), dim=2)
|
| 63 |
+
value = torch.cat((existing[1], value), dim=2)
|
| 64 |
+
self.attention[layer_idx] = (key, value)
|
| 65 |
+
return key, value
|
| 66 |
+
|
| 67 |
+
def update_convolution(self, layer_idx: int, state: torch.Tensor) -> None:
|
| 68 |
+
self.convolution[layer_idx] = state
|
| 69 |
+
|
| 70 |
+
def get_convolution(self, layer_idx: int) -> torch.Tensor | None:
|
| 71 |
+
return self.convolution[layer_idx]
|
| 72 |
+
|
| 73 |
+
def finish_step(self, cache_position: torch.Tensor) -> None:
|
| 74 |
+
if cache_position.numel():
|
| 75 |
+
self.seen_tokens = max(self.seen_tokens, int(cache_position.max()) + 1)
|
| 76 |
+
|
| 77 |
+
def reorder_cache(self, beam_idx: torch.LongTensor) -> QyrouArchHybridCache:
|
| 78 |
+
for index, item in enumerate(self.attention):
|
| 79 |
+
if item is not None:
|
| 80 |
+
self.attention[index] = (
|
| 81 |
+
item[0].index_select(0, beam_idx),
|
| 82 |
+
item[1].index_select(0, beam_idx),
|
| 83 |
+
)
|
| 84 |
+
for index, state in enumerate(self.convolution):
|
| 85 |
+
if state is not None:
|
| 86 |
+
self.convolution[index] = state.index_select(0, beam_idx)
|
| 87 |
+
return self
|
| 88 |
+
|
| 89 |
+
def batch_repeat_interleave(self, repeats: int) -> QyrouArchHybridCache:
|
| 90 |
+
indices = torch.arange(
|
| 91 |
+
next(t[0] for t in self.attention if t is not None).shape[0],
|
| 92 |
+
device=next(t[0] for t in self.attention if t is not None).device,
|
| 93 |
+
).repeat_interleave(repeats)
|
| 94 |
+
return self.reorder_cache(indices)
|
| 95 |
+
|
| 96 |
+
def to_legacy_cache(self) -> tuple[Any, ...]:
|
| 97 |
+
return tuple(self.attention)
|
| 98 |
+
|
resume/checkpoints/qyrou-1-exp-base/checkpoint-step-000680000/model/config.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"architectures": [
|
| 3 |
+
"QyrouArchForCausalLM"
|
| 4 |
+
],
|
| 5 |
+
"attention_backend": "cudnn",
|
| 6 |
+
"auto_map": {
|
| 7 |
+
"AutoConfig": "configuration_qyrou_arch.QyrouArchConfig",
|
| 8 |
+
"AutoModelForCausalLM": "modeling_qyrou_arch.QyrouArchForCausalLM"
|
| 9 |
+
},
|
| 10 |
+
"bos_token_id": 0,
|
| 11 |
+
"conv_kernel_size": 7,
|
| 12 |
+
"conv_layers": [
|
| 13 |
+
4,
|
| 14 |
+
9,
|
| 15 |
+
14,
|
| 16 |
+
19
|
| 17 |
+
],
|
| 18 |
+
"cut_cross_entropy": true,
|
| 19 |
+
"dtype": "float32",
|
| 20 |
+
"eod_token_id": 4,
|
| 21 |
+
"eos_token_id": 1,
|
| 22 |
+
"fused_gate_up_projection": true,
|
| 23 |
+
"fused_qkv_projection": true,
|
| 24 |
+
"hidden_act": "silu",
|
| 25 |
+
"hidden_size": 512,
|
| 26 |
+
"initializer_range": 0.02,
|
| 27 |
+
"intermediate_size": 1328,
|
| 28 |
+
"liger_rms_norm": true,
|
| 29 |
+
"liger_swiglu": true,
|
| 30 |
+
"max_position_embeddings": 2048,
|
| 31 |
+
"model_type": "qyrou_arch",
|
| 32 |
+
"num_attention_heads": 8,
|
| 33 |
+
"num_hidden_layers": 21,
|
| 34 |
+
"num_key_value_heads": 2,
|
| 35 |
+
"pad_token_id": 2,
|
| 36 |
+
"qk_norm": true,
|
| 37 |
+
"residual_initializer_scale": 0.1543033499620919,
|
| 38 |
+
"rms_norm_eps": 1e-05,
|
| 39 |
+
"rope_theta": 10000.0,
|
| 40 |
+
"tie_word_embeddings": true,
|
| 41 |
+
"transformers_version": "5.13.0",
|
| 42 |
+
"unk_token_id": 3,
|
| 43 |
+
"use_cache": true,
|
| 44 |
+
"vocab_size": 20000
|
| 45 |
+
}
|
resume/checkpoints/qyrou-1-exp-base/checkpoint-step-000680000/model/configuration_qyrou_arch.py
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from typing import Any
|
| 4 |
+
|
| 5 |
+
try:
|
| 6 |
+
from transformers import PretrainedConfig
|
| 7 |
+
except ImportError:
|
| 8 |
+
class PretrainedConfig: # type: ignore[no-redef]
|
| 9 |
+
model_type = "qyrou_arch"
|
| 10 |
+
|
| 11 |
+
def __init__(self, **kwargs: Any) -> None:
|
| 12 |
+
for key, value in kwargs.items():
|
| 13 |
+
setattr(self, key, value)
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
class QyrouArchConfig(PretrainedConfig):
|
| 17 |
+
model_type = "qyrou_arch"
|
| 18 |
+
|
| 19 |
+
def __init__(
|
| 20 |
+
self,
|
| 21 |
+
vocab_size: int = 20_000,
|
| 22 |
+
hidden_size: int = 512,
|
| 23 |
+
num_hidden_layers: int = 21,
|
| 24 |
+
num_attention_heads: int = 8,
|
| 25 |
+
num_key_value_heads: int = 2,
|
| 26 |
+
intermediate_size: int = 1_328,
|
| 27 |
+
conv_layers: list[int] | None = None,
|
| 28 |
+
conv_kernel_size: int = 7,
|
| 29 |
+
rope_theta: float = 10_000.0,
|
| 30 |
+
rms_norm_eps: float = 1e-5,
|
| 31 |
+
max_position_embeddings: int = 2_048,
|
| 32 |
+
initializer_range: float = 0.02,
|
| 33 |
+
residual_initializer_scale: float = 1.0 / (42.0**0.5),
|
| 34 |
+
tie_word_embeddings: bool = True,
|
| 35 |
+
qk_norm: bool = True,
|
| 36 |
+
attention_backend: str = "cudnn",
|
| 37 |
+
fused_qkv_projection: bool = True,
|
| 38 |
+
fused_gate_up_projection: bool = True,
|
| 39 |
+
liger_rms_norm: bool = True,
|
| 40 |
+
liger_swiglu: bool = True,
|
| 41 |
+
cut_cross_entropy: bool = True,
|
| 42 |
+
use_cache: bool = True,
|
| 43 |
+
eod_token_id: int = 4,
|
| 44 |
+
**kwargs: Any,
|
| 45 |
+
) -> None:
|
| 46 |
+
super().__init__(tie_word_embeddings=tie_word_embeddings, **kwargs)
|
| 47 |
+
if hidden_size % num_attention_heads:
|
| 48 |
+
raise ValueError("hidden_size must be divisible by num_attention_heads")
|
| 49 |
+
if num_attention_heads % num_key_value_heads:
|
| 50 |
+
raise ValueError("num_attention_heads must be divisible by num_key_value_heads")
|
| 51 |
+
conv_layers = conv_layers if conv_layers is not None else [4, 9, 14, 19]
|
| 52 |
+
if len(set(conv_layers)) != len(conv_layers) or not all(
|
| 53 |
+
1 <= layer <= num_hidden_layers for layer in conv_layers
|
| 54 |
+
):
|
| 55 |
+
raise ValueError("conv_layers must contain unique one-based layer indices")
|
| 56 |
+
self.vocab_size = vocab_size
|
| 57 |
+
self.hidden_size = hidden_size
|
| 58 |
+
self.num_hidden_layers = num_hidden_layers
|
| 59 |
+
self.num_attention_heads = num_attention_heads
|
| 60 |
+
self.num_key_value_heads = num_key_value_heads
|
| 61 |
+
self.intermediate_size = intermediate_size
|
| 62 |
+
self.conv_layers = conv_layers
|
| 63 |
+
self.conv_kernel_size = conv_kernel_size
|
| 64 |
+
self.rope_theta = rope_theta
|
| 65 |
+
self.rms_norm_eps = rms_norm_eps
|
| 66 |
+
self.max_position_embeddings = max_position_embeddings
|
| 67 |
+
self.initializer_range = initializer_range
|
| 68 |
+
self.residual_initializer_scale = residual_initializer_scale
|
| 69 |
+
self.qk_norm = qk_norm
|
| 70 |
+
self.attention_backend = attention_backend
|
| 71 |
+
self.fused_qkv_projection = fused_qkv_projection
|
| 72 |
+
self.fused_gate_up_projection = fused_gate_up_projection
|
| 73 |
+
self.liger_rms_norm = liger_rms_norm
|
| 74 |
+
self.liger_swiglu = liger_swiglu
|
| 75 |
+
self.cut_cross_entropy = cut_cross_entropy
|
| 76 |
+
self.use_cache = use_cache
|
| 77 |
+
self.eod_token_id = eod_token_id
|
| 78 |
+
self.hidden_act = "silu"
|
| 79 |
+
|
resume/checkpoints/qyrou-1-exp-base/checkpoint-step-000680000/model/generation_config.json
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"_from_model_config": true,
|
| 3 |
+
"bos_token_id": 0,
|
| 4 |
+
"eos_token_id": 1,
|
| 5 |
+
"output_attentions": false,
|
| 6 |
+
"output_hidden_states": false,
|
| 7 |
+
"pad_token_id": 2,
|
| 8 |
+
"transformers_version": "5.13.0",
|
| 9 |
+
"use_cache": true
|
| 10 |
+
}
|
resume/checkpoints/qyrou-1-exp-base/checkpoint-step-000680000/model/model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:15e793a9c28db4f2c843a4369363170c619ac1c73fdc4e1c98ffef5a9ca07f23
|
| 3 |
+
size 261234016
|
resume/checkpoints/qyrou-1-exp-base/checkpoint-step-000680000/model/modeling_qyrou_arch.py
ADDED
|
@@ -0,0 +1,504 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from typing import Any
|
| 4 |
+
|
| 5 |
+
import torch
|
| 6 |
+
import torch.nn as nn
|
| 7 |
+
import torch.nn.functional as F
|
| 8 |
+
from torch.nn.attention import SDPBackend, sdpa_kernel
|
| 9 |
+
from transformers import PreTrainedModel
|
| 10 |
+
from transformers.generation import GenerationMixin
|
| 11 |
+
from transformers.modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast
|
| 12 |
+
|
| 13 |
+
from .cache import QyrouArchHybridCache
|
| 14 |
+
from .configuration_qyrou_arch import QyrouArchConfig
|
| 15 |
+
|
| 16 |
+
try:
|
| 17 |
+
from .triton_kernels import PackedSwiGLUFunction
|
| 18 |
+
except (ImportError, RuntimeError):
|
| 19 |
+
PackedSwiGLUFunction = None
|
| 20 |
+
|
| 21 |
+
try:
|
| 22 |
+
from liger_kernel.ops.rms_norm import LigerRMSNormFunction
|
| 23 |
+
from liger_kernel.ops.swiglu import LigerSiLUMulFunction
|
| 24 |
+
except ImportError:
|
| 25 |
+
LigerRMSNormFunction = None
|
| 26 |
+
LigerSiLUMulFunction = None
|
| 27 |
+
|
| 28 |
+
try:
|
| 29 |
+
from cut_cross_entropy import linear_cross_entropy as cut_linear_cross_entropy
|
| 30 |
+
except ImportError:
|
| 31 |
+
cut_linear_cross_entropy = None
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
class RMSNorm(nn.Module):
|
| 35 |
+
def __init__(self, dim: int, eps: float, use_liger: bool = False) -> None:
|
| 36 |
+
super().__init__()
|
| 37 |
+
self.weight = nn.Parameter(torch.ones(dim))
|
| 38 |
+
self.eps = eps
|
| 39 |
+
self.use_liger = use_liger
|
| 40 |
+
|
| 41 |
+
def forward(self, x: torch.Tensor) -> torch.Tensor:
|
| 42 |
+
if (
|
| 43 |
+
x.is_cuda
|
| 44 |
+
and self.use_liger
|
| 45 |
+
and LigerRMSNormFunction is not None
|
| 46 |
+
and not torch.compiler.is_compiling()
|
| 47 |
+
):
|
| 48 |
+
return LigerRMSNormFunction.apply(x, self.weight, self.eps, 0.0, "llama", False, None)
|
| 49 |
+
x_float = x.float()
|
| 50 |
+
normalized = x_float * torch.rsqrt(x_float.square().mean(-1, keepdim=True) + self.eps)
|
| 51 |
+
return normalized.to(x.dtype) * self.weight.to(x.dtype)
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
def _apply_rope(
|
| 55 |
+
x: torch.Tensor,
|
| 56 |
+
cos: torch.Tensor,
|
| 57 |
+
sin: torch.Tensor,
|
| 58 |
+
) -> torch.Tensor:
|
| 59 |
+
even, odd = x[..., 0::2], x[..., 1::2]
|
| 60 |
+
return torch.stack((even * cos - odd * sin, even * sin + odd * cos), dim=-1).flatten(-2)
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def _last_valid_state(
|
| 64 |
+
x: torch.Tensor,
|
| 65 |
+
mask: torch.Tensor | None,
|
| 66 |
+
state_length: int,
|
| 67 |
+
) -> torch.Tensor:
|
| 68 |
+
if state_length == 0:
|
| 69 |
+
return x[:, :0]
|
| 70 |
+
if mask is None:
|
| 71 |
+
return F.pad(x, (0, 0, max(0, state_length - x.shape[1]), 0))[:, -state_length:]
|
| 72 |
+
result = torch.zeros(
|
| 73 |
+
(x.shape[0], state_length, x.shape[2]),
|
| 74 |
+
dtype=x.dtype,
|
| 75 |
+
device=x.device,
|
| 76 |
+
)
|
| 77 |
+
for batch_index in range(x.shape[0]):
|
| 78 |
+
valid = x[batch_index][mask[batch_index].bool()]
|
| 79 |
+
valid = valid[-state_length:]
|
| 80 |
+
result[batch_index, -valid.shape[0] :] = valid
|
| 81 |
+
return result
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
class CausalGQA(nn.Module):
|
| 85 |
+
def __init__(self, config: QyrouArchConfig, layer_idx: int) -> None:
|
| 86 |
+
super().__init__()
|
| 87 |
+
self.layer_idx = layer_idx
|
| 88 |
+
self.num_heads = config.num_attention_heads
|
| 89 |
+
self.num_kv_heads = config.num_key_value_heads
|
| 90 |
+
self.head_dim = config.hidden_size // config.num_attention_heads
|
| 91 |
+
self.q_size = self.num_heads * self.head_dim
|
| 92 |
+
self.kv_size = self.num_kv_heads * self.head_dim
|
| 93 |
+
self.attention_backend = config.attention_backend
|
| 94 |
+
if config.fused_qkv_projection:
|
| 95 |
+
self.qkv_proj = nn.Linear(config.hidden_size, self.q_size + 2 * self.kv_size, bias=False)
|
| 96 |
+
else:
|
| 97 |
+
self.q_proj = nn.Linear(config.hidden_size, self.q_size, bias=False)
|
| 98 |
+
self.k_proj = nn.Linear(config.hidden_size, self.kv_size, bias=False)
|
| 99 |
+
self.v_proj = nn.Linear(config.hidden_size, self.kv_size, bias=False)
|
| 100 |
+
self.o_proj = nn.Linear(config.hidden_size, config.hidden_size, bias=False)
|
| 101 |
+
self.o_proj._qyrou_arch_residual_projection = True # type: ignore[attr-defined]
|
| 102 |
+
self.q_norm = RMSNorm(self.head_dim, config.rms_norm_eps) if config.qk_norm else nn.Identity()
|
| 103 |
+
self.k_norm = RMSNorm(self.head_dim, config.rms_norm_eps) if config.qk_norm else nn.Identity()
|
| 104 |
+
|
| 105 |
+
def forward(
|
| 106 |
+
self,
|
| 107 |
+
x: torch.Tensor,
|
| 108 |
+
rope: tuple[torch.Tensor, torch.Tensor],
|
| 109 |
+
attention_mask: torch.Tensor | None,
|
| 110 |
+
cache: QyrouArchHybridCache | None,
|
| 111 |
+
cache_position: torch.Tensor,
|
| 112 |
+
) -> torch.Tensor:
|
| 113 |
+
batch, query_length, _ = x.shape
|
| 114 |
+
if hasattr(self, "qkv_proj"):
|
| 115 |
+
q, k, v = self.qkv_proj(x).split((self.q_size, self.kv_size, self.kv_size), dim=-1)
|
| 116 |
+
else:
|
| 117 |
+
q, k, v = self.q_proj(x), self.k_proj(x), self.v_proj(x)
|
| 118 |
+
q = q.view(batch, query_length, self.num_heads, self.head_dim).transpose(1, 2)
|
| 119 |
+
k = k.view(batch, query_length, self.num_kv_heads, self.head_dim).transpose(1, 2)
|
| 120 |
+
v = v.view(batch, query_length, self.num_kv_heads, self.head_dim).transpose(1, 2)
|
| 121 |
+
q, k = self.q_norm(q), self.k_norm(k)
|
| 122 |
+
q = _apply_rope(q, *rope)
|
| 123 |
+
k = _apply_rope(k, *rope)
|
| 124 |
+
if cache is not None:
|
| 125 |
+
k, v = cache.update_attention(self.layer_idx, k, v, cache_position)
|
| 126 |
+
key_length = k.shape[2]
|
| 127 |
+
|
| 128 |
+
mask = None
|
| 129 |
+
use_fast_causal = cache is None and attention_mask is None
|
| 130 |
+
if not use_fast_causal:
|
| 131 |
+
key_positions = torch.arange(key_length, device=x.device)
|
| 132 |
+
allowed = key_positions[None, :] <= cache_position[:, None]
|
| 133 |
+
mask = allowed[None, None, :, :].expand(batch, 1, query_length, key_length)
|
| 134 |
+
if attention_mask is not None:
|
| 135 |
+
if attention_mask.shape[-1] < key_length:
|
| 136 |
+
raise ValueError("attention_mask is shorter than the cached key sequence")
|
| 137 |
+
mask = mask & attention_mask[:, None, None, :key_length].bool()
|
| 138 |
+
if q.is_cuda and self.attention_backend in {"cudnn", "flash"}:
|
| 139 |
+
backends = (
|
| 140 |
+
[SDPBackend.CUDNN_ATTENTION, SDPBackend.FLASH_ATTENTION, SDPBackend.MATH]
|
| 141 |
+
if self.attention_backend == "cudnn"
|
| 142 |
+
else [SDPBackend.FLASH_ATTENTION, SDPBackend.CUDNN_ATTENTION, SDPBackend.MATH]
|
| 143 |
+
)
|
| 144 |
+
with sdpa_kernel(
|
| 145 |
+
backends,
|
| 146 |
+
set_priority=True,
|
| 147 |
+
):
|
| 148 |
+
output = F.scaled_dot_product_attention(
|
| 149 |
+
q,
|
| 150 |
+
k,
|
| 151 |
+
v,
|
| 152 |
+
attn_mask=mask,
|
| 153 |
+
is_causal=use_fast_causal,
|
| 154 |
+
enable_gqa=True,
|
| 155 |
+
)
|
| 156 |
+
else:
|
| 157 |
+
output = F.scaled_dot_product_attention(
|
| 158 |
+
q,
|
| 159 |
+
k,
|
| 160 |
+
v,
|
| 161 |
+
attn_mask=mask,
|
| 162 |
+
is_causal=use_fast_causal,
|
| 163 |
+
enable_gqa=True,
|
| 164 |
+
)
|
| 165 |
+
output = output.transpose(1, 2).contiguous().view(batch, query_length, -1)
|
| 166 |
+
return self.o_proj(output)
|
| 167 |
+
|
| 168 |
+
|
| 169 |
+
class CausalConvMixer(nn.Module):
|
| 170 |
+
def __init__(self, config: QyrouArchConfig, layer_idx: int) -> None:
|
| 171 |
+
super().__init__()
|
| 172 |
+
self.layer_idx = layer_idx
|
| 173 |
+
self.kernel_size = config.conv_kernel_size
|
| 174 |
+
self.depthwise = nn.Conv1d(
|
| 175 |
+
config.hidden_size,
|
| 176 |
+
config.hidden_size,
|
| 177 |
+
kernel_size=self.kernel_size,
|
| 178 |
+
groups=config.hidden_size,
|
| 179 |
+
bias=False,
|
| 180 |
+
)
|
| 181 |
+
self.pointwise = nn.Linear(config.hidden_size, config.hidden_size, bias=False)
|
| 182 |
+
self.pointwise._qyrou_arch_residual_projection = True # type: ignore[attr-defined]
|
| 183 |
+
|
| 184 |
+
def forward(
|
| 185 |
+
self,
|
| 186 |
+
x: torch.Tensor,
|
| 187 |
+
_rope: tuple[torch.Tensor, torch.Tensor],
|
| 188 |
+
attention_mask: torch.Tensor | None,
|
| 189 |
+
cache: QyrouArchHybridCache | None,
|
| 190 |
+
_cache_position: torch.Tensor,
|
| 191 |
+
) -> torch.Tensor:
|
| 192 |
+
state_length = self.kernel_size - 1
|
| 193 |
+
query_mask = attention_mask[:, -x.shape[1] :] if attention_mask is not None else None
|
| 194 |
+
if query_mask is not None:
|
| 195 |
+
x = x * query_mask.unsqueeze(-1).to(x.dtype)
|
| 196 |
+
if cache is None:
|
| 197 |
+
conv_input = F.pad(x.transpose(1, 2), (state_length, 0))
|
| 198 |
+
else:
|
| 199 |
+
previous = cache.get_convolution(self.layer_idx)
|
| 200 |
+
if previous is None:
|
| 201 |
+
previous = torch.zeros(
|
| 202 |
+
(x.shape[0], state_length, x.shape[2]),
|
| 203 |
+
dtype=x.dtype,
|
| 204 |
+
device=x.device,
|
| 205 |
+
)
|
| 206 |
+
combined = torch.cat((previous, x), dim=1)
|
| 207 |
+
conv_input = combined.transpose(1, 2)
|
| 208 |
+
combined_mask = None
|
| 209 |
+
if query_mask is not None:
|
| 210 |
+
combined_mask = torch.cat(
|
| 211 |
+
(
|
| 212 |
+
torch.ones(
|
| 213 |
+
(x.shape[0], state_length),
|
| 214 |
+
dtype=query_mask.dtype,
|
| 215 |
+
device=query_mask.device,
|
| 216 |
+
),
|
| 217 |
+
query_mask,
|
| 218 |
+
),
|
| 219 |
+
dim=1,
|
| 220 |
+
)
|
| 221 |
+
cache.update_convolution(
|
| 222 |
+
self.layer_idx,
|
| 223 |
+
_last_valid_state(combined, combined_mask, state_length),
|
| 224 |
+
)
|
| 225 |
+
return self.pointwise(self.depthwise(conv_input).transpose(1, 2))
|
| 226 |
+
|
| 227 |
+
|
| 228 |
+
class SwiGLU(nn.Module):
|
| 229 |
+
def __init__(self, config: QyrouArchConfig) -> None:
|
| 230 |
+
super().__init__()
|
| 231 |
+
self.intermediate_size = config.intermediate_size
|
| 232 |
+
self.use_liger = config.liger_swiglu
|
| 233 |
+
if config.fused_gate_up_projection:
|
| 234 |
+
self.gate_up_proj = nn.Linear(config.hidden_size, 2 * config.intermediate_size, bias=False)
|
| 235 |
+
else:
|
| 236 |
+
self.gate_proj = nn.Linear(config.hidden_size, config.intermediate_size, bias=False)
|
| 237 |
+
self.up_proj = nn.Linear(config.hidden_size, config.intermediate_size, bias=False)
|
| 238 |
+
self.down_proj = nn.Linear(config.intermediate_size, config.hidden_size, bias=False)
|
| 239 |
+
self.down_proj._qyrou_arch_residual_projection = True # type: ignore[attr-defined]
|
| 240 |
+
|
| 241 |
+
def forward(self, x: torch.Tensor) -> torch.Tensor:
|
| 242 |
+
if hasattr(self, "gate_up_proj"):
|
| 243 |
+
packed = self.gate_up_proj(x)
|
| 244 |
+
if (
|
| 245 |
+
packed.is_cuda
|
| 246 |
+
and self.use_liger
|
| 247 |
+
and PackedSwiGLUFunction is not None
|
| 248 |
+
and not torch.compiler.is_compiling()
|
| 249 |
+
):
|
| 250 |
+
return self.down_proj(PackedSwiGLUFunction.apply(packed))
|
| 251 |
+
gate, up = packed.chunk(2, dim=-1)
|
| 252 |
+
else:
|
| 253 |
+
gate, up = self.gate_proj(x), self.up_proj(x)
|
| 254 |
+
if torch.compiler.is_compiling():
|
| 255 |
+
activated = F.silu(gate) * up
|
| 256 |
+
elif x.is_cuda and self.use_liger and LigerSiLUMulFunction is not None:
|
| 257 |
+
activated = LigerSiLUMulFunction.apply(gate, up, 1.0, 1.0)
|
| 258 |
+
else:
|
| 259 |
+
activated = F.silu(gate) * up
|
| 260 |
+
return self.down_proj(activated)
|
| 261 |
+
|
| 262 |
+
|
| 263 |
+
class QyrouArchBlock(nn.Module):
|
| 264 |
+
def __init__(self, config: QyrouArchConfig, layer_idx: int) -> None:
|
| 265 |
+
super().__init__()
|
| 266 |
+
self.mixer_norm = RMSNorm(config.hidden_size, config.rms_norm_eps, config.liger_rms_norm)
|
| 267 |
+
self.ffn_norm = RMSNorm(config.hidden_size, config.rms_norm_eps, config.liger_rms_norm)
|
| 268 |
+
layer_number = layer_idx + 1
|
| 269 |
+
self.mixer = (
|
| 270 |
+
CausalConvMixer(config, layer_idx)
|
| 271 |
+
if layer_number in config.conv_layers
|
| 272 |
+
else CausalGQA(config, layer_idx)
|
| 273 |
+
)
|
| 274 |
+
self.ffn = SwiGLU(config)
|
| 275 |
+
|
| 276 |
+
def forward(
|
| 277 |
+
self,
|
| 278 |
+
x: torch.Tensor,
|
| 279 |
+
rope: tuple[torch.Tensor, torch.Tensor],
|
| 280 |
+
attention_mask: torch.Tensor | None,
|
| 281 |
+
cache: QyrouArchHybridCache | None,
|
| 282 |
+
cache_position: torch.Tensor,
|
| 283 |
+
) -> torch.Tensor:
|
| 284 |
+
x = x + self.mixer(self.mixer_norm(x), rope, attention_mask, cache, cache_position)
|
| 285 |
+
return x + self.ffn(self.ffn_norm(x))
|
| 286 |
+
|
| 287 |
+
|
| 288 |
+
class QyrouArchPreTrainedModel(PreTrainedModel):
|
| 289 |
+
config_class = QyrouArchConfig
|
| 290 |
+
base_model_prefix = "model"
|
| 291 |
+
supports_gradient_checkpointing = False
|
| 292 |
+
_no_split_modules = ["QyrouArchBlock"]
|
| 293 |
+
|
| 294 |
+
def _init_weights(self, module: nn.Module) -> None:
|
| 295 |
+
if isinstance(module, (nn.Linear, nn.Embedding, nn.Conv1d)):
|
| 296 |
+
scale = (
|
| 297 |
+
self.config.residual_initializer_scale
|
| 298 |
+
if getattr(module, "_qyrou_arch_residual_projection", False)
|
| 299 |
+
else 1.0
|
| 300 |
+
)
|
| 301 |
+
nn.init.normal_(module.weight, mean=0.0, std=self.config.initializer_range * scale)
|
| 302 |
+
|
| 303 |
+
|
| 304 |
+
class QyrouArchModel(QyrouArchPreTrainedModel):
|
| 305 |
+
def __init__(self, config: QyrouArchConfig) -> None:
|
| 306 |
+
super().__init__(config)
|
| 307 |
+
self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size)
|
| 308 |
+
self.layers = nn.ModuleList(
|
| 309 |
+
[QyrouArchBlock(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
|
| 310 |
+
)
|
| 311 |
+
self.norm = RMSNorm(config.hidden_size, config.rms_norm_eps, config.liger_rms_norm)
|
| 312 |
+
head_dim = config.hidden_size // config.num_attention_heads
|
| 313 |
+
inv_freq = 1.0 / (
|
| 314 |
+
config.rope_theta ** (torch.arange(0, head_dim, 2).float() / head_dim)
|
| 315 |
+
)
|
| 316 |
+
positions = torch.arange(config.max_position_embeddings, dtype=torch.float32)
|
| 317 |
+
angles = torch.outer(positions, inv_freq)
|
| 318 |
+
self.register_buffer("rope_cos", angles.cos(), persistent=False)
|
| 319 |
+
self.register_buffer("rope_sin", angles.sin(), persistent=False)
|
| 320 |
+
self.post_init()
|
| 321 |
+
|
| 322 |
+
def _rope(
|
| 323 |
+
self,
|
| 324 |
+
position_ids: torch.Tensor,
|
| 325 |
+
dtype: torch.dtype,
|
| 326 |
+
) -> tuple[torch.Tensor, torch.Tensor]:
|
| 327 |
+
if (
|
| 328 |
+
not torch.compiler.is_compiling()
|
| 329 |
+
and int(position_ids.max()) >= self.config.max_position_embeddings
|
| 330 |
+
):
|
| 331 |
+
raise ValueError("Position exceeds max_position_embeddings")
|
| 332 |
+
cos = self.rope_cos[position_ids].to(dtype).unsqueeze(1)
|
| 333 |
+
sin = self.rope_sin[position_ids].to(dtype).unsqueeze(1)
|
| 334 |
+
return cos, sin
|
| 335 |
+
|
| 336 |
+
def forward(
|
| 337 |
+
self,
|
| 338 |
+
input_ids: torch.LongTensor | None = None,
|
| 339 |
+
attention_mask: torch.Tensor | None = None,
|
| 340 |
+
position_ids: torch.LongTensor | None = None,
|
| 341 |
+
past_key_values: QyrouArchHybridCache | None = None,
|
| 342 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 343 |
+
use_cache: bool | None = None,
|
| 344 |
+
cache_position: torch.LongTensor | None = None,
|
| 345 |
+
return_dict: bool | None = None,
|
| 346 |
+
**_: Any,
|
| 347 |
+
) -> BaseModelOutputWithPast | tuple[torch.Tensor, QyrouArchHybridCache | None]:
|
| 348 |
+
if (input_ids is None) == (inputs_embeds is None):
|
| 349 |
+
raise ValueError("Pass exactly one of input_ids or inputs_embeds")
|
| 350 |
+
hidden = self.embed_tokens(input_ids) if inputs_embeds is None else inputs_embeds
|
| 351 |
+
if hidden.is_cuda and torch.is_autocast_enabled("cuda"):
|
| 352 |
+
hidden = hidden.to(torch.get_autocast_dtype("cuda"))
|
| 353 |
+
batch, query_length, _ = hidden.shape
|
| 354 |
+
use_cache = self.config.use_cache if use_cache is None else use_cache
|
| 355 |
+
return_dict = self.config.return_dict if return_dict is None else return_dict
|
| 356 |
+
if use_cache and past_key_values is None:
|
| 357 |
+
past_key_values = QyrouArchHybridCache(self.config.num_hidden_layers)
|
| 358 |
+
cache = past_key_values if use_cache else None
|
| 359 |
+
past_length = cache.get_seq_length() if cache is not None else 0
|
| 360 |
+
if cache_position is None:
|
| 361 |
+
cache_position = torch.arange(
|
| 362 |
+
past_length,
|
| 363 |
+
past_length + query_length,
|
| 364 |
+
device=hidden.device,
|
| 365 |
+
)
|
| 366 |
+
if position_ids is None:
|
| 367 |
+
if attention_mask is not None:
|
| 368 |
+
position_ids = attention_mask.long().cumsum(-1).sub(1).clamp_min(0)[:, -query_length:]
|
| 369 |
+
else:
|
| 370 |
+
position_ids = cache_position.unsqueeze(0).expand(batch, -1)
|
| 371 |
+
rope = self._rope(position_ids, hidden.dtype)
|
| 372 |
+
for layer in self.layers:
|
| 373 |
+
hidden = layer(hidden, rope, attention_mask, cache, cache_position)
|
| 374 |
+
hidden = self.norm(hidden)
|
| 375 |
+
if cache is not None:
|
| 376 |
+
cache.finish_step(cache_position)
|
| 377 |
+
if not return_dict:
|
| 378 |
+
return hidden, cache
|
| 379 |
+
return BaseModelOutputWithPast(last_hidden_state=hidden, past_key_values=cache)
|
| 380 |
+
|
| 381 |
+
|
| 382 |
+
class QyrouArchForCausalLM(QyrouArchPreTrainedModel, GenerationMixin):
|
| 383 |
+
_tied_weights_keys = {"lm_head.weight": "model.embed_tokens.weight"}
|
| 384 |
+
|
| 385 |
+
def __init__(self, config: QyrouArchConfig) -> None:
|
| 386 |
+
super().__init__(config)
|
| 387 |
+
self.model = QyrouArchModel(config)
|
| 388 |
+
self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
|
| 389 |
+
self.post_init()
|
| 390 |
+
self.tie_weights()
|
| 391 |
+
|
| 392 |
+
def get_input_embeddings(self) -> nn.Module:
|
| 393 |
+
return self.model.embed_tokens
|
| 394 |
+
|
| 395 |
+
def set_input_embeddings(self, value: nn.Module) -> None:
|
| 396 |
+
self.model.embed_tokens = value
|
| 397 |
+
|
| 398 |
+
def get_output_embeddings(self) -> nn.Module:
|
| 399 |
+
return self.lm_head
|
| 400 |
+
|
| 401 |
+
def set_output_embeddings(self, value: nn.Module) -> None:
|
| 402 |
+
self.lm_head = value
|
| 403 |
+
|
| 404 |
+
def forward(
|
| 405 |
+
self,
|
| 406 |
+
input_ids: torch.LongTensor | None = None,
|
| 407 |
+
attention_mask: torch.Tensor | None = None,
|
| 408 |
+
position_ids: torch.LongTensor | None = None,
|
| 409 |
+
past_key_values: QyrouArchHybridCache | None = None,
|
| 410 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 411 |
+
labels: torch.LongTensor | None = None,
|
| 412 |
+
use_cache: bool | None = None,
|
| 413 |
+
cache_position: torch.LongTensor | None = None,
|
| 414 |
+
return_logits: bool = True,
|
| 415 |
+
return_dict: bool | None = None,
|
| 416 |
+
**kwargs: Any,
|
| 417 |
+
) -> CausalLMOutputWithPast | tuple[Any, ...]:
|
| 418 |
+
return_dict = self.config.return_dict if return_dict is None else return_dict
|
| 419 |
+
outputs = self.model(
|
| 420 |
+
input_ids=input_ids,
|
| 421 |
+
attention_mask=attention_mask,
|
| 422 |
+
position_ids=position_ids,
|
| 423 |
+
past_key_values=past_key_values,
|
| 424 |
+
inputs_embeds=inputs_embeds,
|
| 425 |
+
use_cache=use_cache,
|
| 426 |
+
cache_position=cache_position,
|
| 427 |
+
return_dict=True,
|
| 428 |
+
**kwargs,
|
| 429 |
+
)
|
| 430 |
+
hidden = outputs.last_hidden_state
|
| 431 |
+
training_loss_only = labels is not None and not return_logits
|
| 432 |
+
logits = None if training_loss_only else self.lm_head(hidden)
|
| 433 |
+
loss = None
|
| 434 |
+
if labels is not None:
|
| 435 |
+
if (
|
| 436 |
+
training_loss_only
|
| 437 |
+
and hidden.is_cuda
|
| 438 |
+
and self.config.cut_cross_entropy
|
| 439 |
+
and cut_linear_cross_entropy is not None
|
| 440 |
+
):
|
| 441 |
+
loss = cut_linear_cross_entropy(
|
| 442 |
+
hidden,
|
| 443 |
+
self.lm_head.weight,
|
| 444 |
+
labels,
|
| 445 |
+
shift=True,
|
| 446 |
+
filter_eps=None,
|
| 447 |
+
)
|
| 448 |
+
else:
|
| 449 |
+
loss_logits = self.lm_head(hidden[:, :-1]).float()
|
| 450 |
+
loss = F.cross_entropy(
|
| 451 |
+
loss_logits.reshape(-1, self.config.vocab_size),
|
| 452 |
+
labels[:, 1:].contiguous().view(-1),
|
| 453 |
+
ignore_index=-100,
|
| 454 |
+
)
|
| 455 |
+
if not return_dict:
|
| 456 |
+
return loss, logits, outputs.past_key_values
|
| 457 |
+
return CausalLMOutputWithPast(
|
| 458 |
+
loss=loss,
|
| 459 |
+
logits=logits,
|
| 460 |
+
past_key_values=outputs.past_key_values,
|
| 461 |
+
)
|
| 462 |
+
|
| 463 |
+
def prepare_inputs_for_generation(
|
| 464 |
+
self,
|
| 465 |
+
input_ids: torch.LongTensor,
|
| 466 |
+
past_key_values: QyrouArchHybridCache | None = None,
|
| 467 |
+
attention_mask: torch.Tensor | None = None,
|
| 468 |
+
cache_position: torch.LongTensor | None = None,
|
| 469 |
+
use_cache: bool = True,
|
| 470 |
+
**kwargs: Any,
|
| 471 |
+
) -> dict[str, Any]:
|
| 472 |
+
past_length = past_key_values.get_seq_length() if past_key_values is not None else 0
|
| 473 |
+
if past_length:
|
| 474 |
+
input_ids = (
|
| 475 |
+
input_ids[:, past_length:]
|
| 476 |
+
if input_ids.shape[1] > past_length
|
| 477 |
+
else input_ids[:, -1:]
|
| 478 |
+
)
|
| 479 |
+
if cache_position is None:
|
| 480 |
+
cache_position = torch.arange(
|
| 481 |
+
past_length,
|
| 482 |
+
past_length + input_ids.shape[1],
|
| 483 |
+
device=input_ids.device,
|
| 484 |
+
)
|
| 485 |
+
elif cache_position.numel() != input_ids.shape[1]:
|
| 486 |
+
cache_position = cache_position[-input_ids.shape[1] :]
|
| 487 |
+
return {
|
| 488 |
+
"input_ids": input_ids,
|
| 489 |
+
"attention_mask": attention_mask,
|
| 490 |
+
"past_key_values": past_key_values,
|
| 491 |
+
"cache_position": cache_position,
|
| 492 |
+
"use_cache": use_cache,
|
| 493 |
+
}
|
| 494 |
+
|
| 495 |
+
def _reorder_cache(
|
| 496 |
+
self,
|
| 497 |
+
past_key_values: QyrouArchHybridCache,
|
| 498 |
+
beam_idx: torch.LongTensor,
|
| 499 |
+
) -> QyrouArchHybridCache:
|
| 500 |
+
return past_key_values.reorder_cache(beam_idx)
|
| 501 |
+
|
| 502 |
+
|
| 503 |
+
QyrouArchConfig.register_for_auto_class()
|
| 504 |
+
QyrouArchForCausalLM.register_for_auto_class("AutoModelForCausalLM")
|
resume/checkpoints/qyrou-1-exp-base/checkpoint-step-000680000/model/triton_kernels.py
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
import torch
|
| 4 |
+
import triton
|
| 5 |
+
import triton.language as tl
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
def _settings(n_cols: int) -> tuple[int, int]:
|
| 9 |
+
block_size = triton.next_power_of_2(n_cols)
|
| 10 |
+
if block_size > 65_536:
|
| 11 |
+
raise ValueError(f"Unsupported SwiGLU width: {n_cols}")
|
| 12 |
+
num_warps = 4 if block_size < 2_048 else 8
|
| 13 |
+
return block_size, num_warps
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
@triton.jit
|
| 17 |
+
def _packed_swiglu_forward_kernel(
|
| 18 |
+
packed_ptr,
|
| 19 |
+
output_ptr,
|
| 20 |
+
packed_stride: tl.constexpr,
|
| 21 |
+
output_stride: tl.constexpr,
|
| 22 |
+
n_cols: tl.constexpr,
|
| 23 |
+
block_size: tl.constexpr,
|
| 24 |
+
):
|
| 25 |
+
row = tl.program_id(0).to(tl.int64)
|
| 26 |
+
offsets = tl.arange(0, block_size)
|
| 27 |
+
mask = offsets < n_cols
|
| 28 |
+
packed_row = packed_ptr + row * packed_stride
|
| 29 |
+
gate = tl.load(packed_row + offsets, mask=mask, other=0.0).to(tl.float32)
|
| 30 |
+
up = tl.load(packed_row + n_cols + offsets, mask=mask, other=0.0)
|
| 31 |
+
activated = (gate * tl.sigmoid(gate)).cast(up.dtype) * up
|
| 32 |
+
tl.store(output_ptr + row * output_stride + offsets, activated, mask=mask)
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
@triton.jit
|
| 36 |
+
def _packed_swiglu_backward_kernel(
|
| 37 |
+
grad_output_ptr,
|
| 38 |
+
packed_ptr,
|
| 39 |
+
grad_packed_ptr,
|
| 40 |
+
grad_output_stride: tl.constexpr,
|
| 41 |
+
packed_stride: tl.constexpr,
|
| 42 |
+
n_cols: tl.constexpr,
|
| 43 |
+
block_size: tl.constexpr,
|
| 44 |
+
):
|
| 45 |
+
row = tl.program_id(0).to(tl.int64)
|
| 46 |
+
offsets = tl.arange(0, block_size)
|
| 47 |
+
mask = offsets < n_cols
|
| 48 |
+
packed_row = packed_ptr + row * packed_stride
|
| 49 |
+
grad_packed_row = grad_packed_ptr + row * packed_stride
|
| 50 |
+
grad_output = tl.load(
|
| 51 |
+
grad_output_ptr + row * grad_output_stride + offsets,
|
| 52 |
+
mask=mask,
|
| 53 |
+
other=0.0,
|
| 54 |
+
)
|
| 55 |
+
gate = tl.load(packed_row + offsets, mask=mask, other=0.0).to(tl.float32)
|
| 56 |
+
up = tl.load(packed_row + n_cols + offsets, mask=mask, other=0.0)
|
| 57 |
+
sigmoid_gate = tl.sigmoid(gate)
|
| 58 |
+
silu_gate = gate * sigmoid_gate
|
| 59 |
+
grad_up = grad_output * silu_gate
|
| 60 |
+
grad_gate = grad_output * up * (sigmoid_gate + silu_gate * (1.0 - sigmoid_gate))
|
| 61 |
+
tl.store(grad_packed_row + offsets, grad_gate, mask=mask)
|
| 62 |
+
tl.store(grad_packed_row + n_cols + offsets, grad_up, mask=mask)
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
class PackedSwiGLUFunction(torch.autograd.Function):
|
| 66 |
+
@staticmethod
|
| 67 |
+
def forward(ctx, packed: torch.Tensor) -> torch.Tensor:
|
| 68 |
+
if not packed.is_cuda:
|
| 69 |
+
raise ValueError("PackedSwiGLUFunction requires a CUDA tensor")
|
| 70 |
+
if packed.dtype not in (torch.float16, torch.bfloat16, torch.float32):
|
| 71 |
+
raise TypeError(f"Unsupported PackedSwiGLU dtype: {packed.dtype}")
|
| 72 |
+
if packed.shape[-1] % 2:
|
| 73 |
+
raise ValueError("Packed gate/up dimension must be even")
|
| 74 |
+
packed = packed.contiguous()
|
| 75 |
+
n_cols = packed.shape[-1] // 2
|
| 76 |
+
packed_2d = packed.view(-1, 2 * n_cols)
|
| 77 |
+
output = torch.empty((packed_2d.shape[0], n_cols), dtype=packed.dtype, device=packed.device)
|
| 78 |
+
block_size, num_warps = _settings(n_cols)
|
| 79 |
+
_packed_swiglu_forward_kernel[(packed_2d.shape[0],)](
|
| 80 |
+
packed_2d,
|
| 81 |
+
output,
|
| 82 |
+
packed_2d.stride(0),
|
| 83 |
+
output.stride(0),
|
| 84 |
+
n_cols=n_cols,
|
| 85 |
+
block_size=block_size,
|
| 86 |
+
num_warps=num_warps,
|
| 87 |
+
)
|
| 88 |
+
ctx.save_for_backward(packed_2d)
|
| 89 |
+
ctx.original_shape = packed.shape
|
| 90 |
+
ctx.n_cols = n_cols
|
| 91 |
+
ctx.block_size = block_size
|
| 92 |
+
ctx.num_warps = num_warps
|
| 93 |
+
return output.view(*packed.shape[:-1], n_cols)
|
| 94 |
+
|
| 95 |
+
@staticmethod
|
| 96 |
+
def backward(ctx, grad_output: torch.Tensor) -> tuple[torch.Tensor]:
|
| 97 |
+
(packed_2d,) = ctx.saved_tensors
|
| 98 |
+
grad_output_2d = grad_output.contiguous().view(-1, ctx.n_cols)
|
| 99 |
+
grad_packed = torch.empty_like(packed_2d)
|
| 100 |
+
_packed_swiglu_backward_kernel[(packed_2d.shape[0],)](
|
| 101 |
+
grad_output_2d,
|
| 102 |
+
packed_2d,
|
| 103 |
+
grad_packed,
|
| 104 |
+
grad_output_2d.stride(0),
|
| 105 |
+
packed_2d.stride(0),
|
| 106 |
+
n_cols=ctx.n_cols,
|
| 107 |
+
block_size=ctx.block_size,
|
| 108 |
+
num_warps=ctx.num_warps,
|
| 109 |
+
)
|
| 110 |
+
return (grad_packed.view(ctx.original_shape),)
|
resume/checkpoints/qyrou-1-exp-base/checkpoint-step-000680000/training_state.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:06ed8c306ade8342a16f73be3c4eb327bc1ce1f88900a772e3f4731872870031
|
| 3 |
+
size 526781105
|
resume/checkpoints/qyrou-1-exp-base/index.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"version": 1,
|
| 3 |
+
"checkpoints": [
|
| 4 |
+
{
|
| 5 |
+
"path": "checkpoint-step-000680000",
|
| 6 |
+
"step": 680000,
|
| 7 |
+
"total_tokens": 33423360000,
|
| 8 |
+
"validation_loss": null,
|
| 9 |
+
"bytes": 788049493,
|
| 10 |
+
"protected_reasons": [
|
| 11 |
+
"hub-backup"
|
| 12 |
+
]
|
| 13 |
+
}
|
| 14 |
+
],
|
| 15 |
+
"best": null
|
| 16 |
+
}
|
resume/checkpoints/qyrou-1-exp-base/latest.json
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"version": 1,
|
| 3 |
+
"path": "checkpoint-step-000680000",
|
| 4 |
+
"step": 680000,
|
| 5 |
+
"total_tokens": 33423360000
|
| 6 |
+
}
|
resume/configs/qyrou_1_exp_base.json
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"run": {
|
| 3 |
+
"name": "qyrou-1-exp-base",
|
| 4 |
+
"seed": 1337,
|
| 5 |
+
"project_dir": "D:\\qyrou_1_exp_base",
|
| 6 |
+
"dataset_dir": "C:\\Dataset_qyrou_1\\Qyrou_PT_Corpus_English",
|
| 7 |
+
"tokenizer_dir": "D:\\qyrou_1_exp_base\\artifacts\\tokenizer",
|
| 8 |
+
"token_cache_dir": "D:\\qyrou_1_exp_base\\data\\tokenized",
|
| 9 |
+
"checkpoint_dir": "D:\\qyrou_1_exp_base\\checkpoints\\qyrou-1-exp-base",
|
| 10 |
+
"log_dir": "D:\\qyrou_1_exp_base\\runs\\qyrou-1-exp-base",
|
| 11 |
+
"final_dir": "D:\\qyrou_1_exp_base\\final\\qyrou-1-exp-base"
|
| 12 |
+
},
|
| 13 |
+
"model": {
|
| 14 |
+
"vocab_size": 20000,
|
| 15 |
+
"hidden_size": 512,
|
| 16 |
+
"num_hidden_layers": 21,
|
| 17 |
+
"num_attention_heads": 8,
|
| 18 |
+
"num_key_value_heads": 2,
|
| 19 |
+
"intermediate_size": 1328,
|
| 20 |
+
"conv_layers": [4, 9, 14, 19],
|
| 21 |
+
"conv_kernel_size": 7,
|
| 22 |
+
"rope_theta": 10000.0,
|
| 23 |
+
"rms_norm_eps": 1e-5,
|
| 24 |
+
"max_position_embeddings": 2048,
|
| 25 |
+
"initializer_range": 0.02,
|
| 26 |
+
"residual_initializer_scale": 0.1543033499620919,
|
| 27 |
+
"tie_word_embeddings": true,
|
| 28 |
+
"qk_norm": true,
|
| 29 |
+
"attention_backend": "cudnn",
|
| 30 |
+
"fused_qkv_projection": true,
|
| 31 |
+
"fused_gate_up_projection": true,
|
| 32 |
+
"liger_rms_norm": true,
|
| 33 |
+
"liger_swiglu": true,
|
| 34 |
+
"cut_cross_entropy": true,
|
| 35 |
+
"bos_token_id": 0,
|
| 36 |
+
"eos_token_id": 1,
|
| 37 |
+
"pad_token_id": 2,
|
| 38 |
+
"unk_token_id": 3,
|
| 39 |
+
"eod_token_id": 4
|
| 40 |
+
},
|
| 41 |
+
"tokenizer": {
|
| 42 |
+
"vocab_size": 20000,
|
| 43 |
+
"sample_bytes": 20000000000,
|
| 44 |
+
"min_frequency": 2,
|
| 45 |
+
"batch_size": 256,
|
| 46 |
+
"quality_rows": 20000
|
| 47 |
+
},
|
| 48 |
+
"data": {
|
| 49 |
+
"sequence_length": 2048,
|
| 50 |
+
"minimum_free_gib_before_tokenize": 130,
|
| 51 |
+
"encode_batch_size": 256,
|
| 52 |
+
"write_buffer_tokens": 1048576,
|
| 53 |
+
"parallel_workers": 4,
|
| 54 |
+
"tokenizer_threads_per_worker": 4,
|
| 55 |
+
"shuffle_seed": 1337,
|
| 56 |
+
"shuffle_block_tokens": 65536
|
| 57 |
+
},
|
| 58 |
+
"training": {
|
| 59 |
+
"device": "cuda",
|
| 60 |
+
"dtype": "bf16",
|
| 61 |
+
"peak_learning_rate": 0.00057,
|
| 62 |
+
"minimum_learning_rate": 0.000057,
|
| 63 |
+
"warmup_tokens": 50000000,
|
| 64 |
+
"weight_decay": 0.1,
|
| 65 |
+
"beta1": 0.9,
|
| 66 |
+
"beta2": 0.95,
|
| 67 |
+
"epsilon": 1e-8,
|
| 68 |
+
"grad_clip": 1.0,
|
| 69 |
+
"log_every_steps": 10,
|
| 70 |
+
"save_every_steps": 5000,
|
| 71 |
+
"eval_every_steps": 25000,
|
| 72 |
+
"eval_tokens": 1048576,
|
| 73 |
+
"qualification_steps": 5000,
|
| 74 |
+
"qualification_tokens": 100000000,
|
| 75 |
+
"minimum_tps": 84000,
|
| 76 |
+
"target_tps": 85000,
|
| 77 |
+
"compile_minimum_improvement": 0.03,
|
| 78 |
+
"autotune_candidates": [[5, 3], [6, 3], [6, 4], [8, 2], [8, 3], [10, 2], [12, 2]],
|
| 79 |
+
"max_automatic_recoveries": 2
|
| 80 |
+
},
|
| 81 |
+
"checkpoints": {
|
| 82 |
+
"cap_gib": 50,
|
| 83 |
+
"prune_count": 12,
|
| 84 |
+
"milestone_fractions": [0.1, 0.25, 0.5, 0.75, 0.9, 1.0]
|
| 85 |
+
}
|
| 86 |
+
}
|
source/QYROU_ARCH_ARCHITECTURE_AUDIT.md
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Qyrou-1 65M Architecture Audit
|
| 2 |
+
|
| 3 |
+
Audited preview: `QyrouArchLabs/QyrouArch-65M-Preview` at commit
|
| 4 |
+
`94f25e19b0efb71b4534fe890afb58f5a8e8a4e1`.
|
| 5 |
+
|
| 6 |
+
## Executive assessment
|
| 7 |
+
|
| 8 |
+
The preview is a coherent 65M hybrid causal language model. Its parameter budget is
|
| 9 |
+
well chosen and the training graph is substantially more efficient than a stock
|
| 10 |
+
Llama implementation at the same size. The current repository is a strong
|
| 11 |
+
pretraining preview, but it is not yet a seamless inference release. In
|
| 12 |
+
particular, generation has no KV or convolution state cache and the model ignores
|
| 13 |
+
attention masks, position IDs, and cache-related generation arguments.
|
| 14 |
+
|
| 15 |
+
The recommended Qyrou-1 architecture is therefore the preview architecture with
|
| 16 |
+
its training graph retained and its serving contract completed before release.
|
| 17 |
+
|
| 18 |
+
## Exact architecture
|
| 19 |
+
|
| 20 |
+
| Component | Value |
|
| 21 |
+
|---|---:|
|
| 22 |
+
| Vocabulary | 20,000 |
|
| 23 |
+
| Hidden width | 512 |
|
| 24 |
+
| Layers | 21 |
|
| 25 |
+
| Attention layers | 17 |
|
| 26 |
+
| Causal convolution layers | 4 (`4, 9, 14, 19`) |
|
| 27 |
+
| Attention heads | 8 |
|
| 28 |
+
| KV heads | 2 |
|
| 29 |
+
| Head dimension | 64 |
|
| 30 |
+
| GQA query groups per KV head | 4 |
|
| 31 |
+
| FFN intermediate width | 1,328 |
|
| 32 |
+
| FFN | SwiGLU |
|
| 33 |
+
| Normalization | pre-RMSNorm |
|
| 34 |
+
| Positional encoding | RoPE, theta 10,000 |
|
| 35 |
+
| Context length | 2,048 |
|
| 36 |
+
| Convolution | causal depthwise kernel 7 + dense pointwise projection |
|
| 37 |
+
| Embedding/output head | tied |
|
| 38 |
+
| Biases | none |
|
| 39 |
+
|
| 40 |
+
Each block is:
|
| 41 |
+
|
| 42 |
+
1. `x = x + mixer(RMSNorm(x))`
|
| 43 |
+
2. `x = x + down(SiLU(gate(x)) * up(x))`
|
| 44 |
+
|
| 45 |
+
The mixer is GQA in 17 blocks and a causal convolution in four evenly spaced
|
| 46 |
+
blocks. The convolution layers provide cheap local token mixing; attention layers
|
| 47 |
+
retain global causal communication.
|
| 48 |
+
|
| 49 |
+
## Exact parameter count
|
| 50 |
+
|
| 51 |
+
| Component | Count |
|
| 52 |
+
|---|---:|
|
| 53 |
+
| Tied token embedding / LM head | 10,240,000 |
|
| 54 |
+
| 17 attention blocks | 45,835,264 |
|
| 55 |
+
| 4 convolution blocks | 9,226,240 |
|
| 56 |
+
| Final RMSNorm | 512 |
|
| 57 |
+
| **Total** | **65,302,016** |
|
| 58 |
+
|
| 59 |
+
An attention block has 2,696,192 parameters:
|
| 60 |
+
|
| 61 |
+
- packed QKV projection: 393,216
|
| 62 |
+
- output projection: 262,144
|
| 63 |
+
- SwiGLU projections: 2,039,808
|
| 64 |
+
- two RMSNorm weights: 1,024
|
| 65 |
+
|
| 66 |
+
A convolution block has 2,306,560 parameters:
|
| 67 |
+
|
| 68 |
+
- depthwise convolution: 3,584
|
| 69 |
+
- pointwise projection: 262,144
|
| 70 |
+
- SwiGLU projections: 2,039,808
|
| 71 |
+
- two RMSNorm weights: 1,024
|
| 72 |
+
|
| 73 |
+
## Efficient training paths
|
| 74 |
+
|
| 75 |
+
The preview enables:
|
| 76 |
+
|
| 77 |
+
- one packed QKV GEMM instead of three projection launches;
|
| 78 |
+
- one packed gate/up GEMM instead of two projection launches;
|
| 79 |
+
- a custom Triton packed SwiGLU activation with a custom backward;
|
| 80 |
+
- Liger RMSNorm when installed;
|
| 81 |
+
- cut-cross-entropy, avoiding full `[batch, sequence, vocabulary]` logits during
|
| 82 |
+
loss-only training;
|
| 83 |
+
- cuDNN scaled-dot-product attention with a math fallback;
|
| 84 |
+
- BF16 parameters and fused AdamW;
|
| 85 |
+
- cached RoPE tensors for repeated fixed-length batches.
|
| 86 |
+
|
| 87 |
+
At batch 5 and sequence 2,048, ordinary logits would contain 204.8 million BF16
|
| 88 |
+
values, about 390.6 MiB before gradients and temporaries. Cut cross entropy is
|
| 89 |
+
therefore one of the most important memory optimizations in this model.
|
| 90 |
+
|
| 91 |
+
## Triton kernel audit
|
| 92 |
+
|
| 93 |
+
The custom kernel performs only the packed SwiGLU elementwise operation. The
|
| 94 |
+
gate/up projection itself is a packed PyTorch linear GEMM; it is not fused into
|
| 95 |
+
the Triton activation kernel.
|
| 96 |
+
|
| 97 |
+
The implemented math is correct:
|
| 98 |
+
|
| 99 |
+
- forward: `SiLU(gate) * up`;
|
| 100 |
+
- `d(up) = d(output) * SiLU(gate)`;
|
| 101 |
+
- `d(gate) = d(output) * up * (sigmoid(gate) + SiLU(gate) *
|
| 102 |
+
(1 - sigmoid(gate)))`.
|
| 103 |
+
|
| 104 |
+
Positive properties:
|
| 105 |
+
|
| 106 |
+
- masked tail handling supports the non-power-of-two width 1,328;
|
| 107 |
+
- row indices use 64-bit addressing;
|
| 108 |
+
- non-contiguous packed input is normalized before launch;
|
| 109 |
+
- backward makes the incoming gradient contiguous;
|
| 110 |
+
- the saved tensor is the packed projection rather than extra gate/up copies.
|
| 111 |
+
|
| 112 |
+
Required hardening:
|
| 113 |
+
|
| 114 |
+
- validate that the packed last dimension is even;
|
| 115 |
+
- validate CUDA placement and supported floating dtypes before launching;
|
| 116 |
+
- add reference forward/backward parity tests for BF16 and FP32;
|
| 117 |
+
- add odd/tail-width, non-contiguous input, zero-size, and large-row tests;
|
| 118 |
+
- benchmark against Liger's existing SwiGLU and plain compiled PyTorch;
|
| 119 |
+
- avoid importing `calculate_settings` from Liger inside the custom-kernel module
|
| 120 |
+
if the goal is an independently loadable kernel;
|
| 121 |
+
- document supported Triton and `triton-windows` versions rather than monkey
|
| 122 |
+
patching dependency version checks at import time.
|
| 123 |
+
|
| 124 |
+
## Release blockers
|
| 125 |
+
|
| 126 |
+
### 1. No incremental generation cache
|
| 127 |
+
|
| 128 |
+
`forward` accepts only `input_ids` as an effective model input. Cache-related
|
| 129 |
+
arguments are swallowed and ignored. Every generated token therefore recomputes
|
| 130 |
+
all preceding attention, convolution, FFN, and logits work.
|
| 131 |
+
|
| 132 |
+
Implement:
|
| 133 |
+
|
| 134 |
+
- per-layer K/V cache for all 17 attention layers;
|
| 135 |
+
- six-token rolling state for each kernel-7 convolution layer;
|
| 136 |
+
- cache position and RoPE offset handling;
|
| 137 |
+
- `past_key_values`, `use_cache`, and a cache-aware model output;
|
| 138 |
+
- `prepare_inputs_for_generation` and cache reordering.
|
| 139 |
+
|
| 140 |
+
### 2. Attention masks are ignored
|
| 141 |
+
|
| 142 |
+
Padded batched inference and packed examples can attend to padding or unrelated
|
| 143 |
+
tokens. Accept and correctly combine `attention_mask` with causality. Add tests
|
| 144 |
+
for left padding, right padding, unequal prompt lengths, and fully unpadded
|
| 145 |
+
equivalence.
|
| 146 |
+
|
| 147 |
+
### 3. Position IDs and RoPE offsets are ignored
|
| 148 |
+
|
| 149 |
+
RoPE always begins at zero and is keyed only by sequence length, device, and
|
| 150 |
+
dtype. Incremental decoding and padded batches need explicit positions. Cache
|
| 151 |
+
cosine/sine tables by capacity, then gather using `position_ids`.
|
| 152 |
+
|
| 153 |
+
### 4. Serving outputs do not follow the full Transformers contract
|
| 154 |
+
|
| 155 |
+
Add support for `return_dict`, hidden states when requested, cache outputs, and
|
| 156 |
+
the standard causal-LM generation inputs. Reject unsupported arguments rather
|
| 157 |
+
than silently swallowing every keyword.
|
| 158 |
+
|
| 159 |
+
### 5. Context policy is fixed at 2,048
|
| 160 |
+
|
| 161 |
+
The architecture can run longer, but it was trained at 2,048 with base RoPE.
|
| 162 |
+
Do not advertise longer context without continued pretraining and long-context
|
| 163 |
+
evaluation. If longer context is a Qyrou-1 goal, train it deliberately rather
|
| 164 |
+
than changing `max_position_embeddings` after the fact.
|
| 165 |
+
|
| 166 |
+
## Data and training findings
|
| 167 |
+
|
| 168 |
+
The finalized source dataset is stored at `C:\Dataset_qyrou_1`, with the primary
|
| 169 |
+
corpus under `C:\Dataset_qyrou_1\Qyrou_PT_Corpus_English`.
|
| 170 |
+
|
| 171 |
+
The preview completed 325,521 steps and approximately 9.996B tokens. With batch
|
| 172 |
+
5, gradient accumulation 3, and sequence length 2,048, each optimizer step
|
| 173 |
+
represents 30,720 tokens, which agrees with the recorded total.
|
| 174 |
+
|
| 175 |
+
The local finalized corpus contains 69,330,050 valid records and about 224 GB of
|
| 176 |
+
text. It is much larger than the 10B-token training allocation, so a deterministic
|
| 177 |
+
token-level mixture and sampling policy matters more than merely having enough
|
| 178 |
+
data.
|
| 179 |
+
|
| 180 |
+
Before benchmark reporting:
|
| 181 |
+
|
| 182 |
+
- remove or isolate HellaSwag, WinoGrande, and LAMBADA training examples;
|
| 183 |
+
- deduplicate related math sources across datasets;
|
| 184 |
+
- keep code-license and source provenance outside the text-only training shards;
|
| 185 |
+
- reduce the observed exact-duplicate rate in Stack-derived data;
|
| 186 |
+
- avoid allowing FineWeb-Edu volume to erase curated math, code, tool, and
|
| 187 |
+
high-quality language mixture targets.
|
| 188 |
+
|
| 189 |
+
## Recommended Qyrou-1 65M release design
|
| 190 |
+
|
| 191 |
+
Retain the preview's dimensions and hybrid schedule for the 65M release. Changing
|
| 192 |
+
width, depth, FFN ratio, or convolution placement would discard the value of the
|
| 193 |
+
completed 10B-token preview experiment.
|
| 194 |
+
|
| 195 |
+
Complete the model in this order:
|
| 196 |
+
|
| 197 |
+
1. Establish PyTorch reference tests for attention, convolution, RMSNorm, packed
|
| 198 |
+
SwiGLU, loss shifting, and tied weights.
|
| 199 |
+
2. Add the complete cache and attention-mask serving contract.
|
| 200 |
+
3. Add Triton parity and gradient tests before further fusion.
|
| 201 |
+
4. Benchmark packed GEMMs, SwiGLU, RMSNorm, SDPA, and cross entropy separately.
|
| 202 |
+
5. Add optional optimized paths behind capability checks, preserving a plain
|
| 203 |
+
PyTorch fallback.
|
| 204 |
+
6. Run a short continued-pretraining smoke test from the preview checkpoint.
|
| 205 |
+
7. Evaluate loss/perplexity plus uncontaminated downstream tasks.
|
| 206 |
+
8. Only then consider additional fused residual+RMSNorm or convolution kernels;
|
| 207 |
+
optimize measured bottlenecks, not launch count in isolation.
|
| 208 |
+
|
| 209 |
+
The central design decision is sound: a 512-wide, 21-layer hybrid with 2-KV-head
|
| 210 |
+
GQA and four causal-convolution mixers gives Qyrou-1 a distinct architecture
|
| 211 |
+
while remaining compatible with efficient dense GPU kernels. The immediate work
|
| 212 |
+
is robustness and serving efficiency, not another architectural redesign.
|
source/TRAINING.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Qyrou-1 65M training
|
| 2 |
+
|
| 3 |
+
The source corpus is read-only at
|
| 4 |
+
`C:\Dataset_qyrou_1\Qyrou_PT_Corpus_English`. Generated tokenizer assets,
|
| 5 |
+
uint16 tokens, logs, checkpoints, and the final model stay inside this project
|
| 6 |
+
on D:.
|
| 7 |
+
|
| 8 |
+
## Safe launch order
|
| 9 |
+
|
| 10 |
+
Run from a native Windows PowerShell:
|
| 11 |
+
|
| 12 |
+
```powershell
|
| 13 |
+
.\scripts\bootstrap_windows.ps1
|
| 14 |
+
.\scripts\run_full_training.ps1
|
| 15 |
+
```
|
| 16 |
+
|
| 17 |
+
The pipeline performs hardware/disk checks, trains and validates the tokenizer,
|
| 18 |
+
pretokenizes all 100 corpus shards, prepares fixed validation tokens, runs tests,
|
| 19 |
+
autotunes the RTX 5070, and starts training only after all stages pass.
|
| 20 |
+
|
| 21 |
+
Training does not rewrite the token cache. It divides the existing cache into
|
| 22 |
+
65,536-token contiguous blocks and deterministically shuffles all block
|
| 23 |
+
references with seed 1337. Every token is visited exactly once. Each checkpoint
|
| 24 |
+
stores the complete permutation and exact cursor, and the launcher audits the
|
| 25 |
+
permutation plus a boundary-crossing resume before every training launch.
|
| 26 |
+
|
| 27 |
+
To continue after a controlled interruption:
|
| 28 |
+
|
| 29 |
+
```powershell
|
| 30 |
+
.\scripts\run_full_training.ps1 -StartAt train -Resume
|
| 31 |
+
```
|
| 32 |
+
|
| 33 |
+
Inspect all checkpoint hashes and the 50 GiB retention ledger with:
|
| 34 |
+
|
| 35 |
+
```powershell
|
| 36 |
+
.\.venv\Scripts\python.exe scripts\inspect_checkpoint.py --validate-all
|
| 37 |
+
```
|
| 38 |
+
|
| 39 |
+
The validated compile-safe path targets 85K effective tokens/s and refuses to
|
| 40 |
+
continue past the 5,000-step qualification gate if the median is below 84K.
|
| 41 |
+
The current real-data shuffled-stream smoke test sustains about 87.1K tokens/s
|
| 42 |
+
with microbatch 8 and accumulation 3. Production autotuning rechecks this after
|
| 43 |
+
data preparation. Raw loss is expected to fluctuate; the 100- and 1,000-step
|
| 44 |
+
averages plus fixed validation loss are the convergence signals.
|
source/attribution.md
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Dataset credits
|
| 2 |
+
|
| 3 |
+
This is the list of datasets we used and the people and projects we want to thank. Where a dataset has a paper, we cite it below. Where it does not, we link directly to the Hugging Face page so the original creator is still easy to find.
|
| 4 |
+
|
| 5 |
+
We also keep the dataset name and source with our processed files. That matters because converting something to JSONL does not change who made it or what license it came with.
|
| 6 |
+
|
| 7 |
+
## Datasets
|
| 8 |
+
|
| 9 |
+
| Dataset | Our note | License and citation |
|
| 10 |
+
|---|---|---|
|
| 11 |
+
| [HuggingFaceGECLM/REDDIT_comments](https://huggingface.co/datasets/HuggingFaceGECLM/REDDIT_comments) | Thanks to HuggingFaceGECLM for collecting and organizing the Reddit comments. We sampled the data by subreddit and removed empty, deleted, and removed comments. | The page does not give us a paper to cite, so we link to the dataset itself. The comments came from Reddit and are still subject to Reddit’s terms and the rights of their original authors. |
|
| 12 |
+
| [abisee/cnn_dailymail](https://huggingface.co/datasets/abisee/cnn_dailymail) | Thanks to the CNN/Daily Mail dataset team and the original publishers. We used the articles and highlights from the `3.0.0` training split. | The Hub page lists Apache-2.0 for the dataset package. We cite Hermann et al. and Nallapati et al. below. |
|
| 13 |
+
| [EdinburghNLP/xsum](https://huggingface.co/datasets/EdinburghNLP/xsum) | Thanks to the EdinburghNLP team for XSum and to the BBC for the source material. | We cite Narayan, Cohen, and Lapata below and follow the license information on the dataset page. |
|
| 14 |
+
| [grammarly/coedit](https://huggingface.co/datasets/grammarly/coedit) | Thanks to Grammarly and the CoEdIT authors. We used the source and target edits and kept the edit task where possible. | We cite the CoEdIT paper by Raheja et al. below. |
|
| 15 |
+
| [b-mc2/wikihow_lists](https://huggingface.co/datasets/b-mc2/wikihow_lists) | Thanks to b-mc2 for preparing the dataset and to WikiHow for the original material. | Listed as CC BY-NC-SA 3.0, which means attribution, non-commercial use, and share-alike apply. We cite Koupaee and Wang below. |
|
| 16 |
+
| [agentlans/grammar-correction](https://huggingface.co/datasets/agentlans/grammar-correction) | Thanks to agentlans for publishing the grammar-correction pairs. | We did not find a paper or a clear license on the card, so we cite the dataset page directly and treat the license as unknown. |
|
| 17 |
+
| [Gryphe/ChatGPT-4o-Writing-Prompts](https://huggingface.co/datasets/Gryphe/ChatGPT-4o-Writing-Prompts) | Thanks to Gryphe for publishing the writing-prompt conversations. | No paper or license was listed when we checked, so we link to the dataset page and treat the license as unknown. |
|
| 18 |
+
| [krisha05/story-generation-dataset](https://huggingface.co/datasets/krisha05/story-generation-dataset) | Thanks to krisha05 for the story-generation instruction and response pairs. | We cite the dataset page. We will use the license shown there at the exact revision we downloaded. |
|
| 19 |
+
| [HAD653/gsm8k-cot-120b](https://huggingface.co/datasets/HAD653/gsm8k-cot-120b) | Thanks to HAD653 for this GSM8K-based version and to the original GSM8K team. The reasoning traces are generated additions to the original questions. | We cite both this dataset page and Cobbe et al.’s GSM8K paper below. |
|
| 20 |
+
| [AI-MO/NuminaMath-CoT](https://huggingface.co/datasets/AI-MO/NuminaMath-CoT) | Thanks to the AI-MO and NuminaMath teams, along with the projects that supplied the original problems. | We cite the dataset page and the NuminaMath paper listed there. Individual problem sources may have their own licenses. |
|
| 21 |
+
| [Dogacel/nemotron-post-training-v2-gpt-oss-120b-regen](https://huggingface.co/datasets/Dogacel/nemotron-post-training-v2-gpt-oss-120b-regen) | Thanks to Dogacel for the regenerated set and to the Nemotron contributors named on the card. | This repository changes over time, so we record the exact revision we use and cite the page plus any upstream projects named there. |
|
| 22 |
+
| [Raymond-dev-546730/Open-CoT-Reasoning-Mini](https://huggingface.co/datasets/Raymond-dev-546730/Open-CoT-Reasoning-Mini) | Thanks to Raymond-dev-546730 for publishing the dataset. | The viewer was disabled when we checked. We cite the repository and use the license and source notes included in its files. |
|
| 23 |
+
| [Roman1111111/claude-sonnet-4.6-120000x](https://huggingface.co/datasets/Roman1111111/claude-sonnet-4.6-120000x) | Thanks to Roman1111111 for putting the conversations together. Where the card identifies Claude-generated material, we describe it that way. | We cite the dataset page and follow the terms listed there. This does not imply that Anthropic endorses our work. |
|
| 24 |
+
| [eitanturok/Salesforce-xlam-function-calling-60k](https://huggingface.co/datasets/eitanturok/Salesforce-xlam-function-calling-60k) | Thanks to eitanturok and the Salesforce xLAM team for the function-calling examples. | We cite the dataset page and the xLAM paper or model card linked from it. |
|
| 25 |
+
| [glaiveai/glaive-function-calling-v2](https://huggingface.co/datasets/glaiveai/glaive-function-calling-v2) | Thanks to Glaive AI for publishing the function-calling conversations. | We did not find a separate paper to cite, so we cite the dataset page and follow the license shown there. |
|
| 26 |
+
| [open-web-math/open-web-math](https://huggingface.co/datasets/open-web-math/open-web-math) | Thanks to the OpenWebMath team and to the sites that the material originally came from. We keep source URLs where possible. | We cite the OpenWebMath page and paper. Because this is web data, the original sites may have their own terms and rights. |
|
| 27 |
+
| [nvidia/OpenMathInstruct-1](https://huggingface.co/datasets/nvidia/OpenMathInstruct-1) | Thanks to NVIDIA and the OpenMathInstruct team. Some solutions were generated, so we keep the available correctness information. | We cite the dataset page and the OpenMathInstruct paper linked there. |
|
| 28 |
+
| [TIGER-Lab/MathInstruct](https://huggingface.co/datasets/TIGER-Lab/MathInstruct) | Thanks to TIGER-Lab, the MAmmoTH authors, and the teams behind the component datasets. | We cite Yue et al.’s MAmmoTH paper below. Component datasets may carry additional licenses. |
|
| 29 |
+
| [microsoft/orca-math-word-problems-200k](https://huggingface.co/datasets/microsoft/orca-math-word-problems-200k) | Thanks to Microsoft and the Orca-Math team for the word problems and answers. | We cite the dataset page and the Orca-Math paper linked from it. |
|
| 30 |
+
| [open-thoughts/OpenThoughts3-1.2M](https://huggingface.co/datasets/open-thoughts/OpenThoughts3-1.2M) | Thanks to the OpenThoughts contributors and all of the source projects listed on the card. | We cite the dataset page and its technical report. We keep the source information because this is a mix of several datasets. |
|
| 31 |
+
| [hkust-nlp/dart-math-hard](https://huggingface.co/datasets/hkust-nlp/dart-math-hard) | Thanks to HKUST-NLP and the DART-Math team. We identify this as the hard-sampled version. | We cite the DART-Math paper and dataset page. |
|
| 32 |
+
| [hkust-nlp/dart-math-uniform](https://huggingface.co/datasets/hkust-nlp/dart-math-uniform) | Thanks to HKUST-NLP and the DART-Math team. We identify this as the uniform version. | We cite the same DART-Math paper and this dataset page. |
|
| 33 |
+
| [LLM360/MegaMath](https://huggingface.co/datasets/LLM360/MegaMath) | Thanks to LLM360 and the many projects included in MegaMath. We used selected text-bearing parts rather than every component. | We cite MegaMath and keep the original component information so the individual sources can also be credited. |
|
| 34 |
+
| [HuggingFaceTB/finemath](https://huggingface.co/datasets/HuggingFaceTB/finemath) | Thanks to the Hugging Face team behind FineMath and InfiWebMath. We used the `finemath-4plus` configuration. | We cite the FineMath/FineWeb material linked on the dataset page. The original websites may have their own terms. |
|
| 35 |
+
| [HuggingFaceFW/fineweb-edu](https://huggingface.co/datasets/HuggingFaceFW/fineweb-edu) | Thanks to Anton Lozhkov, Loubna Ben Allal, Leandro von Werra, Thomas Wolf, the wider Hugging Face FineWeb team, and Common Crawl. Our local copy came from the `sample-350BT` configuration, although we only downloaded part of that sample. | FineWeb-Edu is released under ODC-By 1.0 and its use is also subject to Common Crawl's terms. We cite both the dataset and the FineWeb paper below. The original web pages can still carry their own rights and terms. |
|
| 36 |
+
| [math-ai/AutoMathText](https://huggingface.co/datasets/math-ai/AutoMathText) | Thanks to the math-ai team for AutoMathText. We used the requested web score range and kept the text field. | We cite the dataset page and any paper linked there. The source websites may have separate terms. |
|
| 37 |
+
| [open-r1/OpenR1-Math-220k](https://huggingface.co/datasets/open-r1/OpenR1-Math-220k) | Thanks to the Open-R1 contributors and the teams behind the source problems and generated solutions. | We cite the Open-R1 dataset page and technical report, along with the source datasets named there. |
|
| 38 |
+
| [zwhe99/DeepMath-103K](https://huggingface.co/datasets/zwhe99/DeepMath-103K) | Thanks to zwhe99 and the DeepMath contributors. We used the requested `r1_solution_2` field. | We cite the dataset page and any DeepMath paper linked from it. |
|
| 39 |
+
| [ybisk/piqa](https://huggingface.co/datasets/ybisk/piqa) | Thanks to Yonatan Bisk and the PIQA team. | We cite Bisk et al. below. We keep a separate clean evaluation copy. |
|
| 40 |
+
| [Rowan/hellaswag](https://huggingface.co/datasets/Rowan/hellaswag) | Thanks to Rowan Zellers and the HellaSwag team. | The original repository is MIT-licensed. We cite Zellers et al. below and keep a separate evaluation copy. |
|
| 41 |
+
| [allenai/social_i_qa](https://huggingface.co/datasets/allenai/social_i_qa) | Thanks to the Allen Institute for AI and the Social IQa team. | We cite Sap et al. below. The viewer was disabled when we checked, so we also keep the exact repository revision we used. |
|
| 42 |
+
| [allenai/winogrande](https://huggingface.co/datasets/allenai/winogrande) | Thanks to the Allen Institute for AI and the WinoGrande team. We used the debiased training configuration. | We cite Sakaguchi et al. below. The debiased version is listed under Apache-2.0 in the source material we reviewed. |
|
| 43 |
+
| [roneneldan/TinyStories](https://huggingface.co/datasets/roneneldan/TinyStories) | Thanks to Ronen Eldan and Yuanzhi Li for TinyStories. | We cite their TinyStories paper below and the Hugging Face dataset page. |
|
| 44 |
+
| [HuggingFaceCode/stack-v3-train](https://huggingface.co/datasets/HuggingFaceCode/stack-v3-train) | Thanks to the BigCode/Hugging Face team and, importantly, to the developers who wrote the original code. | We keep repository paths and per-file license information. The collection has database-level terms, but every code file still carries its own license. We cite the Stack/BigCode project and paper. |
|
| 45 |
+
| [grimulkan/physical-reasoning](https://huggingface.co/datasets/grimulkan/physical-reasoning) | Thanks to grimulkan for publishing the physical-reasoning examples. | The card leaves some questions about the synthetic source and license, so we cite the page and treat the license as unresolved. |
|
| 46 |
+
| [PixArt-alpha/SAM-LLaVA-Captions10M](https://huggingface.co/datasets/PixArt-alpha/SAM-LLaVA-Captions10M) | Thanks to the PixArt-alpha and SAM-LLaVA contributors. We extracted only the caption text. | We cite the dataset page and the SAM-LLaVA/PixArt work linked there. The captions still trace back to source images and image datasets. |
|
| 47 |
+
| [cimec/lambada](https://huggingface.co/datasets/cimec/lambada) | Thanks to Paperno and the LAMBADA team, and to cimec for the Hugging Face version. | The Hub package is listed as CC BY-4.0. We cite Paperno et al. below and keep evaluation data separate. |
|
| 48 |
+
| [ianncity/GLM-5.2-Conversation](https://huggingface.co/datasets/ianncity/GLM-5.2-Conversation) | Thanks to ianncity and the GLM-related contributors named on the page. | We cite the dataset page and the upstream projects it names. |
|
| 49 |
+
| [deepmind/math_dataset](https://huggingface.co/datasets/deepmind/math_dataset) | Thanks to DeepMind and the authors of the Mathematics Dataset. | We cite Saxton et al. below. The viewer was disabled when we checked, so we keep the exact module, split, and repository revision we use. |
|
| 50 |
+
| [wikimedia/wikipedia](https://huggingface.co/datasets/wikimedia/wikipedia) | Thanks to the Wikimedia community and the editors who wrote and maintained the English Wikipedia articles. We used the `20231101.en` training configuration. | Wikipedia content is available under CC BY-SA 3.0 and the GFDL. We keep the source revision and provide attribution back to Wikimedia and the article authors. |
|
| 51 |
+
| [allenai/peS2o](https://huggingface.co/datasets/allenai/peS2o) | Thanks to the Allen Institute for AI, the peS2o team, Semantic Scholar, and the authors of the original open-access papers. We used English text from the v2 training data. | Listed as ODC-By. We cite the peS2o dataset report and S2ORC source work. |
|
| 52 |
+
| [HuggingFaceTB/cosmopedia](https://huggingface.co/datasets/HuggingFaceTB/cosmopedia) | Thanks to the Hugging Face Cosmopedia team. We used only the Khan Academy, OpenStax, Stanford, and stories configurations. | Listed as Apache-2.0. We cite the dataset page and the projects acknowledged in its README. |
|
| 53 |
+
| [OpenAssistant/oasst2](https://huggingface.co/datasets/OpenAssistant/oasst2) | Thanks to the OpenAssistant contributors who wrote, reviewed, and ranked the conversations. We used reviewed, non-deleted English message trees. | Listed as Apache-2.0. We cite the OASST2 dataset page and the OpenAssistant Conversations paper. |
|
| 54 |
+
|
| 55 |
+
## BibTeX
|
| 56 |
+
|
| 57 |
+
These are the paper citations we have collected so far. For datasets built from other datasets, we also cite the Hugging Face page and the original sources named in its README.
|
| 58 |
+
|
| 59 |
+
```bibtex
|
| 60 |
+
@inproceedings{hermann2015teaching,
|
| 61 |
+
title={Teaching Machines to Read and Comprehend},
|
| 62 |
+
author={Hermann, Karl Moritz and Kočiský, Tomáš and Grefenstette, Edward and Espeholt, Lasse and Kay, Will and Suleyman, Mustafa and Blunsom, Phil},
|
| 63 |
+
booktitle={Advances in Neural Information Processing Systems},
|
| 64 |
+
year={2015}
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
@inproceedings{nallapati2016abstractive,
|
| 68 |
+
title={Abstractive Text Summarization Using Sequence-to-Sequence RNNs and Beyond},
|
| 69 |
+
author={Nallapati, Ramesh and Zhou, Bowen and dos Santos, Cícero Nogueira and Gulcehre, Caglar and Xiang, Bing},
|
| 70 |
+
booktitle={Proceedings of the 20th SIGNLL Conference on Computational Natural Language Learning},
|
| 71 |
+
year={2016}
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
@inproceedings{narayan2018dont,
|
| 75 |
+
title={Don't Give Me the Details, Just the Summary! Topic-Aware Convolutional Neural Networks for Extreme Summarization},
|
| 76 |
+
author={Narayan, Shashi and Cohen, Shay B. and Lapata, Mirella},
|
| 77 |
+
booktitle={Proceedings of EMNLP},
|
| 78 |
+
year={2018}
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
@article{raheja2023coedit,
|
| 82 |
+
title={CoEdIT: Text Editing by Prompting Large Language Models},
|
| 83 |
+
author={Raheja, Vipul and others},
|
| 84 |
+
journal={arXiv preprint arXiv:2305.09857},
|
| 85 |
+
year={2023}
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
@inproceedings{koupaee2018wikihow,
|
| 89 |
+
title={WikiHow: A Large Scale Text Summarization Dataset},
|
| 90 |
+
author={Koupaee, Mahnaz and Wang, William Yang},
|
| 91 |
+
booktitle={Proceedings of the First Workshop on Scholarly Document Processing},
|
| 92 |
+
year={2018}
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
@article{cobbe2021training,
|
| 96 |
+
title={Training Verifiers to Solve Math Word Problems},
|
| 97 |
+
author={Cobbe, Karl and Kosaraju, Vineet and Bavarian, Mohammad and Chen, Mark and Jun, Heewoo and Kaiser, Lukasz and Plappert, Matthias and Tworek, Jerry and Hilton, Jacob and Nakano, Reiichiro and others},
|
| 98 |
+
journal={arXiv preprint arXiv:2110.14168},
|
| 99 |
+
year={2021}
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
@inproceedings{yue2023mammoth,
|
| 103 |
+
title={MAmmoTH: Building Math Generalist Models through Hybrid Instruction Tuning},
|
| 104 |
+
author={Yue, Xiang and others},
|
| 105 |
+
booktitle={Proceedings of ICLR},
|
| 106 |
+
year={2024}
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
@inproceedings{bisk2020piqa,
|
| 110 |
+
title={PIQA: Reasoning about Physical Commonsense in Natural Language},
|
| 111 |
+
author={Bisk, Yonatan and Zellers, Rowan and Gao, Jianfeng and Choi, Yejin},
|
| 112 |
+
booktitle={Proceedings of AAAI},
|
| 113 |
+
year={2020}
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
@inproceedings{zellers2019hellaswag,
|
| 117 |
+
title={HellaSwag: Can a Machine Really Finish Your Sentence?},
|
| 118 |
+
author={Zellers, Rowan and Holtzman, Ari and Bisk, Yonatan and Farhadi, Ali and Choi, Yejin},
|
| 119 |
+
booktitle={Proceedings of ACL},
|
| 120 |
+
year={2019}
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
@inproceedings{sap2019socialiqa,
|
| 124 |
+
title={Social IQa: Commonsense Reasoning about Social Interactions},
|
| 125 |
+
author={Sap, Maarten and Le Bras, Ronan and Allaway, Emily and Bhagavatula, Chandra and Lourie, Nicholas and Rashkin, Hannah and Roof, Brendan and Smith, Noah A. and Choi, Yejin},
|
| 126 |
+
booktitle={Proceedings of EMNLP-IJCNLP},
|
| 127 |
+
year={2019}
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
@inproceedings{sakaguchi2020winogrande,
|
| 131 |
+
title={WinoGrande: An Adversarial Winograd Schema Challenge at Scale},
|
| 132 |
+
author={Sakaguchi, Keisuke and Le Bras, Ronan and Bhagavatula, Chandra and Choi, Yejin},
|
| 133 |
+
booktitle={Proceedings of AAAI},
|
| 134 |
+
year={2020}
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
@article{eldan2023tinystories,
|
| 138 |
+
title={TinyStories: How Small Can Language Models Be and Still Speak Coherent English?},
|
| 139 |
+
author={Eldan, Ronen and Li, Yuanzhi},
|
| 140 |
+
journal={arXiv preprint arXiv:2305.07759},
|
| 141 |
+
year={2023}
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
@misc{lozhkov2024fineweb-edu,
|
| 145 |
+
author={Lozhkov, Anton and Ben Allal, Loubna and von Werra, Leandro and Wolf, Thomas},
|
| 146 |
+
title={FineWeb-Edu: the Finest Collection of Educational Content},
|
| 147 |
+
year={2024},
|
| 148 |
+
url={https://huggingface.co/datasets/HuggingFaceFW/fineweb-edu},
|
| 149 |
+
doi={10.57967/hf/2497},
|
| 150 |
+
publisher={Hugging Face}
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
@inproceedings{paperno2016lambada,
|
| 154 |
+
title={The LAMBADA dataset: Word prediction requiring a broad discourse context},
|
| 155 |
+
author={Paperno, Denis and Kruszewski, Germán and Lazaridou, Angeliki and Pham, Ngoc Quan and Bernardi, Raffaella and Pezzelle, Sandro and Baroni, Marco and Boleda, Gemma and Fernández, Raquel},
|
| 156 |
+
booktitle={Proceedings of ACL},
|
| 157 |
+
year={2016}
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
@inproceedings{saxton2019analysing,
|
| 161 |
+
title={Analysing Mathematical Reasoning Abilities of Neural Models},
|
| 162 |
+
author={Saxton, David and Grefenstette, Edward and Hill, Adam and Kohli, Pushmeet},
|
| 163 |
+
booktitle={Proceedings of ICLR},
|
| 164 |
+
year={2019}
|
| 165 |
+
}
|
| 166 |
+
```
|
| 167 |
+
|
| 168 |
+
## A few notes about how we use the data
|
| 169 |
+
|
| 170 |
+
- Reformatting a dataset does not change its license or ownership.
|
| 171 |
+
- We keep the original dataset name and source information with our processed copies.
|
| 172 |
+
- For Stack v3, we keep the repository and file-level license details because different files can use different licenses.
|
| 173 |
+
- When a dataset contains generated conversations or reasoning, we credit both the person who assembled it and the model or source data behind it.
|
| 174 |
+
- Using a company or project’s dataset does not mean that company or project endorses us.
|
| 175 |
+
- For PIQA, HellaSwag, Social IQa, WinoGrande, LAMBADA, and DeepMind Math, we keep a clean evaluation copy and note any training use.
|
| 176 |
+
- Before we publish anything, we save the exact README, license files, and commit SHA that went with the version we downloaded.
|
source/pyproject.toml
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[build-system]
|
| 2 |
+
requires = ["setuptools>=75", "wheel"]
|
| 3 |
+
build-backend = "setuptools.build_meta"
|
| 4 |
+
|
| 5 |
+
[project]
|
| 6 |
+
name = "qyrou_arch-training"
|
| 7 |
+
version = "0.1.0"
|
| 8 |
+
description = "Qyrou-1 65M pretraining, evaluation, and inference stack"
|
| 9 |
+
requires-python = ">=3.12,<3.13"
|
| 10 |
+
dependencies = [
|
| 11 |
+
"datasets>=4,<5",
|
| 12 |
+
"numpy==2.4.6",
|
| 13 |
+
"psutil>=6.1,<7",
|
| 14 |
+
"safetensors>=0.8,<0.9",
|
| 15 |
+
"tokenizers==0.22.2",
|
| 16 |
+
"transformers==5.13.0",
|
| 17 |
+
]
|
| 18 |
+
|
| 19 |
+
[project.optional-dependencies]
|
| 20 |
+
train = [
|
| 21 |
+
"cut-cross-entropy==25.1.1",
|
| 22 |
+
"liger-kernel==0.8.0",
|
| 23 |
+
"triton-windows==3.7.1.post27; platform_system == 'Windows'",
|
| 24 |
+
]
|
| 25 |
+
test = ["pytest>=8.3,<9"]
|
| 26 |
+
|
| 27 |
+
[tool.setuptools.packages.find]
|
| 28 |
+
include = ["qyrou_arch*"]
|
| 29 |
+
|
| 30 |
+
[tool.pytest.ini_options]
|
| 31 |
+
testpaths = ["tests"]
|
| 32 |
+
addopts = "-ra"
|
source/qyrou_arch/__init__.py
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Qyrou-1 model and training stack."""
|
| 2 |
+
|
| 3 |
+
from .configuration_qyrou_arch import QyrouArchConfig
|
| 4 |
+
|
| 5 |
+
__all__ = ["QyrouArchConfig"]
|
| 6 |
+
|
source/qyrou_arch/cache.py
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from dataclasses import dataclass, field
|
| 4 |
+
from typing import Any
|
| 5 |
+
|
| 6 |
+
import torch
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
@dataclass
|
| 10 |
+
class QyrouArchHybridCache:
|
| 11 |
+
"""Attention K/V plus short-convolution state for incremental decoding."""
|
| 12 |
+
|
| 13 |
+
num_layers: int
|
| 14 |
+
max_cache_len: int | None = None
|
| 15 |
+
attention: list[tuple[torch.Tensor, torch.Tensor] | None] = field(init=False)
|
| 16 |
+
convolution: list[torch.Tensor | None] = field(init=False)
|
| 17 |
+
seen_tokens: int = 0
|
| 18 |
+
|
| 19 |
+
def __post_init__(self) -> None:
|
| 20 |
+
self.attention = [None] * self.num_layers
|
| 21 |
+
self.convolution = [None] * self.num_layers
|
| 22 |
+
if self.max_cache_len is not None and self.max_cache_len <= 0:
|
| 23 |
+
raise ValueError("max_cache_len must be positive")
|
| 24 |
+
|
| 25 |
+
@property
|
| 26 |
+
def is_static(self) -> bool:
|
| 27 |
+
return self.max_cache_len is not None
|
| 28 |
+
|
| 29 |
+
def get_seq_length(self, _layer_idx: int = 0) -> int:
|
| 30 |
+
return self.seen_tokens
|
| 31 |
+
|
| 32 |
+
def get_max_cache_shape(self) -> int | None:
|
| 33 |
+
return self.max_cache_len
|
| 34 |
+
|
| 35 |
+
def update_attention(
|
| 36 |
+
self,
|
| 37 |
+
layer_idx: int,
|
| 38 |
+
key: torch.Tensor,
|
| 39 |
+
value: torch.Tensor,
|
| 40 |
+
cache_position: torch.Tensor,
|
| 41 |
+
) -> tuple[torch.Tensor, torch.Tensor]:
|
| 42 |
+
if key.ndim != 4 or key.shape != value.shape:
|
| 43 |
+
raise ValueError("K/V cache tensors must have identical [batch, heads, seq, dim] shapes")
|
| 44 |
+
if self.is_static:
|
| 45 |
+
assert self.max_cache_len is not None
|
| 46 |
+
if int(cache_position.max()) >= self.max_cache_len:
|
| 47 |
+
raise ValueError("Static cache capacity exceeded")
|
| 48 |
+
existing = self.attention[layer_idx]
|
| 49 |
+
if existing is None:
|
| 50 |
+
shape = (*key.shape[:2], self.max_cache_len, key.shape[-1])
|
| 51 |
+
key_cache = torch.zeros(shape, dtype=key.dtype, device=key.device)
|
| 52 |
+
value_cache = torch.zeros(shape, dtype=value.dtype, device=value.device)
|
| 53 |
+
else:
|
| 54 |
+
key_cache, value_cache = existing
|
| 55 |
+
key_cache.index_copy_(2, cache_position, key)
|
| 56 |
+
value_cache.index_copy_(2, cache_position, value)
|
| 57 |
+
self.attention[layer_idx] = (key_cache, value_cache)
|
| 58 |
+
visible = max(self.seen_tokens, int(cache_position.max()) + 1)
|
| 59 |
+
return key_cache[:, :, :visible], value_cache[:, :, :visible]
|
| 60 |
+
existing = self.attention[layer_idx]
|
| 61 |
+
if existing is not None:
|
| 62 |
+
key = torch.cat((existing[0], key), dim=2)
|
| 63 |
+
value = torch.cat((existing[1], value), dim=2)
|
| 64 |
+
self.attention[layer_idx] = (key, value)
|
| 65 |
+
return key, value
|
| 66 |
+
|
| 67 |
+
def update_convolution(self, layer_idx: int, state: torch.Tensor) -> None:
|
| 68 |
+
self.convolution[layer_idx] = state
|
| 69 |
+
|
| 70 |
+
def get_convolution(self, layer_idx: int) -> torch.Tensor | None:
|
| 71 |
+
return self.convolution[layer_idx]
|
| 72 |
+
|
| 73 |
+
def finish_step(self, cache_position: torch.Tensor) -> None:
|
| 74 |
+
if cache_position.numel():
|
| 75 |
+
self.seen_tokens = max(self.seen_tokens, int(cache_position.max()) + 1)
|
| 76 |
+
|
| 77 |
+
def reorder_cache(self, beam_idx: torch.LongTensor) -> QyrouArchHybridCache:
|
| 78 |
+
for index, item in enumerate(self.attention):
|
| 79 |
+
if item is not None:
|
| 80 |
+
self.attention[index] = (
|
| 81 |
+
item[0].index_select(0, beam_idx),
|
| 82 |
+
item[1].index_select(0, beam_idx),
|
| 83 |
+
)
|
| 84 |
+
for index, state in enumerate(self.convolution):
|
| 85 |
+
if state is not None:
|
| 86 |
+
self.convolution[index] = state.index_select(0, beam_idx)
|
| 87 |
+
return self
|
| 88 |
+
|
| 89 |
+
def batch_repeat_interleave(self, repeats: int) -> QyrouArchHybridCache:
|
| 90 |
+
indices = torch.arange(
|
| 91 |
+
next(t[0] for t in self.attention if t is not None).shape[0],
|
| 92 |
+
device=next(t[0] for t in self.attention if t is not None).device,
|
| 93 |
+
).repeat_interleave(repeats)
|
| 94 |
+
return self.reorder_cache(indices)
|
| 95 |
+
|
| 96 |
+
def to_legacy_cache(self) -> tuple[Any, ...]:
|
| 97 |
+
return tuple(self.attention)
|
| 98 |
+
|
source/qyrou_arch/chat_template.jinja
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{%- for message in messages %}
|
| 2 |
+
{%- if message['role'] not in ['system', 'developer', 'user', 'assistant', 'tool', 'function', 'observation'] %}
|
| 3 |
+
{{- raise_exception('Unsupported QyrouArch chat role: ' + message['role']) }}
|
| 4 |
+
{%- endif %}
|
| 5 |
+
{{- '<|im_start|><|' + message['role'] + '|>\n' + message['content'] + '<|im_end|>\n' }}
|
| 6 |
+
{%- endfor %}
|
| 7 |
+
{%- if add_generation_prompt %}
|
| 8 |
+
{{- '<|im_start|><|assistant|>\n' }}
|
| 9 |
+
{%- endif %}
|
| 10 |
+
|
source/qyrou_arch/checkpointing.py
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
import json
|
| 4 |
+
import os
|
| 5 |
+
import shutil
|
| 6 |
+
import time
|
| 7 |
+
import uuid
|
| 8 |
+
from pathlib import Path
|
| 9 |
+
from typing import Any
|
| 10 |
+
|
| 11 |
+
import torch
|
| 12 |
+
|
| 13 |
+
from .io_utils import atomic_write_json, read_json, sha256_file
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def directory_size(path: Path) -> int:
|
| 17 |
+
return sum(item.stat().st_size for item in path.rglob("*") if item.is_file())
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
class CheckpointManager:
|
| 21 |
+
def __init__(self, root: str | Path, cap_gib: float = 50, prune_count: int = 12) -> None:
|
| 22 |
+
self.root = Path(root).resolve()
|
| 23 |
+
self.root.mkdir(parents=True, exist_ok=True)
|
| 24 |
+
self.cap_bytes = int(cap_gib * 2**30)
|
| 25 |
+
self.prune_count = prune_count
|
| 26 |
+
self.index_path = self.root / "index.json"
|
| 27 |
+
self.latest_path = self.root / "latest.json"
|
| 28 |
+
if not self.index_path.exists():
|
| 29 |
+
atomic_write_json(self.index_path, {"version": 1, "checkpoints": [], "best": None})
|
| 30 |
+
|
| 31 |
+
def _index(self) -> dict[str, Any]:
|
| 32 |
+
return read_json(self.index_path)
|
| 33 |
+
|
| 34 |
+
def storage_bytes(self) -> int:
|
| 35 |
+
return directory_size(self.root)
|
| 36 |
+
|
| 37 |
+
def _validate_delete_target(self, path: Path) -> None:
|
| 38 |
+
resolved = path.resolve()
|
| 39 |
+
if resolved.parent != self.root or not resolved.name.startswith("checkpoint-step-"):
|
| 40 |
+
raise RuntimeError(f"Refusing unsafe checkpoint deletion target: {resolved}")
|
| 41 |
+
|
| 42 |
+
def _prune_before_save(self, projected_bytes: int) -> None:
|
| 43 |
+
if self.storage_bytes() + projected_bytes <= self.cap_bytes:
|
| 44 |
+
return
|
| 45 |
+
index = self._index()
|
| 46 |
+
latest = read_json(self.latest_path).get("path") if self.latest_path.exists() else None
|
| 47 |
+
best = index.get("best")
|
| 48 |
+
eligible = [
|
| 49 |
+
entry
|
| 50 |
+
for entry in sorted(index["checkpoints"], key=lambda item: item["step"])
|
| 51 |
+
if entry["path"] not in {latest, best}
|
| 52 |
+
and not entry.get("protected_reasons")
|
| 53 |
+
]
|
| 54 |
+
if len(eligible) < self.prune_count:
|
| 55 |
+
raise RuntimeError(
|
| 56 |
+
f"Checkpoint cap requires pruning, but only {len(eligible)} unprotected checkpoints exist"
|
| 57 |
+
)
|
| 58 |
+
deleted = {entry["path"] for entry in eligible[: self.prune_count]}
|
| 59 |
+
for relative in deleted:
|
| 60 |
+
target = self.root / relative
|
| 61 |
+
self._validate_delete_target(target)
|
| 62 |
+
shutil.rmtree(target)
|
| 63 |
+
index["checkpoints"] = [
|
| 64 |
+
entry for entry in index["checkpoints"] if entry["path"] not in deleted
|
| 65 |
+
]
|
| 66 |
+
atomic_write_json(self.index_path, index)
|
| 67 |
+
|
| 68 |
+
def save(
|
| 69 |
+
self,
|
| 70 |
+
*,
|
| 71 |
+
model: Any,
|
| 72 |
+
optimizer: torch.optim.Optimizer,
|
| 73 |
+
trainer_state: dict[str, Any],
|
| 74 |
+
step: int,
|
| 75 |
+
total_tokens: int,
|
| 76 |
+
validation_loss: float | None = None,
|
| 77 |
+
expected_bytes: int | None = None,
|
| 78 |
+
) -> Path:
|
| 79 |
+
self._prune_before_save(expected_bytes or 2**30)
|
| 80 |
+
name = f"checkpoint-step-{step:09d}"
|
| 81 |
+
final_path = self.root / name
|
| 82 |
+
if final_path.exists():
|
| 83 |
+
raise RuntimeError(f"Checkpoint already exists: {final_path}")
|
| 84 |
+
temporary = self.root / f".tmp-{name}-{uuid.uuid4().hex}"
|
| 85 |
+
temporary.mkdir()
|
| 86 |
+
model_dir = temporary / "model"
|
| 87 |
+
model.save_pretrained(model_dir, safe_serialization=True)
|
| 88 |
+
torch.save(
|
| 89 |
+
{
|
| 90 |
+
"version": 1,
|
| 91 |
+
"optimizer": optimizer.state_dict(),
|
| 92 |
+
"trainer": trainer_state,
|
| 93 |
+
"cpu_rng": torch.get_rng_state(),
|
| 94 |
+
"cuda_rng": torch.cuda.get_rng_state_all() if torch.cuda.is_available() else None,
|
| 95 |
+
},
|
| 96 |
+
temporary / "training_state.pt",
|
| 97 |
+
)
|
| 98 |
+
files = []
|
| 99 |
+
for path in sorted(temporary.rglob("*")):
|
| 100 |
+
if path.is_file():
|
| 101 |
+
files.append(
|
| 102 |
+
{
|
| 103 |
+
"path": str(path.relative_to(temporary)),
|
| 104 |
+
"bytes": path.stat().st_size,
|
| 105 |
+
"sha256": sha256_file(path),
|
| 106 |
+
}
|
| 107 |
+
)
|
| 108 |
+
atomic_write_json(
|
| 109 |
+
temporary / "manifest.json",
|
| 110 |
+
{
|
| 111 |
+
"version": 1,
|
| 112 |
+
"step": step,
|
| 113 |
+
"total_tokens": total_tokens,
|
| 114 |
+
"validation_loss": validation_loss,
|
| 115 |
+
"created_at": time.time(),
|
| 116 |
+
"files": files,
|
| 117 |
+
},
|
| 118 |
+
)
|
| 119 |
+
os.replace(temporary, final_path)
|
| 120 |
+
if not self.validate(final_path):
|
| 121 |
+
raise RuntimeError(f"New checkpoint failed validation: {final_path}")
|
| 122 |
+
|
| 123 |
+
index = self._index()
|
| 124 |
+
entry = {
|
| 125 |
+
"path": name,
|
| 126 |
+
"step": step,
|
| 127 |
+
"total_tokens": total_tokens,
|
| 128 |
+
"validation_loss": validation_loss,
|
| 129 |
+
"bytes": directory_size(final_path),
|
| 130 |
+
"protected_reasons": [],
|
| 131 |
+
}
|
| 132 |
+
index["checkpoints"].append(entry)
|
| 133 |
+
if validation_loss is not None:
|
| 134 |
+
current_best = index.get("best")
|
| 135 |
+
current_entry = next(
|
| 136 |
+
(item for item in index["checkpoints"] if item["path"] == current_best),
|
| 137 |
+
None,
|
| 138 |
+
)
|
| 139 |
+
if current_entry is None or validation_loss < current_entry["validation_loss"]:
|
| 140 |
+
index["best"] = name
|
| 141 |
+
atomic_write_json(self.index_path, index)
|
| 142 |
+
atomic_write_json(
|
| 143 |
+
self.latest_path,
|
| 144 |
+
{"version": 1, "path": name, "step": step, "total_tokens": total_tokens},
|
| 145 |
+
)
|
| 146 |
+
return final_path
|
| 147 |
+
|
| 148 |
+
def validate(self, path: str | Path) -> bool:
|
| 149 |
+
path = Path(path)
|
| 150 |
+
try:
|
| 151 |
+
manifest = read_json(path / "manifest.json")
|
| 152 |
+
for entry in manifest["files"]:
|
| 153 |
+
file_path = path / entry["path"]
|
| 154 |
+
if file_path.stat().st_size != entry["bytes"]:
|
| 155 |
+
return False
|
| 156 |
+
if sha256_file(file_path) != entry["sha256"]:
|
| 157 |
+
return False
|
| 158 |
+
torch.load(path / "training_state.pt", map_location="cpu", weights_only=False)
|
| 159 |
+
return True
|
| 160 |
+
except (OSError, KeyError, ValueError, RuntimeError, json.JSONDecodeError):
|
| 161 |
+
return False
|
| 162 |
+
|
| 163 |
+
def find_latest_valid(self) -> Path | None:
|
| 164 |
+
index = self._index()
|
| 165 |
+
for entry in sorted(index["checkpoints"], key=lambda item: item["step"], reverse=True):
|
| 166 |
+
path = self.root / entry["path"]
|
| 167 |
+
if self.validate(path):
|
| 168 |
+
return path
|
| 169 |
+
return None
|
| 170 |
+
|
| 171 |
+
def load_training_state(self, path: str | Path) -> dict[str, Any]:
|
| 172 |
+
path = Path(path)
|
| 173 |
+
if not self.validate(path):
|
| 174 |
+
raise RuntimeError(f"Invalid checkpoint: {path}")
|
| 175 |
+
return torch.load(path / "training_state.pt", map_location="cpu", weights_only=False)
|
| 176 |
+
|
| 177 |
+
def save_milestone(self, model: Any, fraction: float, step: int, total_tokens: int) -> Path:
|
| 178 |
+
milestones = self.root / "milestones"
|
| 179 |
+
milestones.mkdir(exist_ok=True)
|
| 180 |
+
destination = milestones / f"milestone-{int(fraction * 100):03d}pct"
|
| 181 |
+
if destination.exists():
|
| 182 |
+
return destination
|
| 183 |
+
temporary = milestones / f".tmp-{destination.name}-{uuid.uuid4().hex}"
|
| 184 |
+
model.save_pretrained(temporary, safe_serialization=True)
|
| 185 |
+
atomic_write_json(
|
| 186 |
+
temporary / "milestone.json",
|
| 187 |
+
{"fraction": fraction, "step": step, "total_tokens": total_tokens},
|
| 188 |
+
)
|
| 189 |
+
os.replace(temporary, destination)
|
| 190 |
+
return destination
|
source/qyrou_arch/configuration_qyrou_arch.py
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from typing import Any
|
| 4 |
+
|
| 5 |
+
try:
|
| 6 |
+
from transformers import PretrainedConfig
|
| 7 |
+
except ImportError:
|
| 8 |
+
class PretrainedConfig: # type: ignore[no-redef]
|
| 9 |
+
model_type = "qyrou_arch"
|
| 10 |
+
|
| 11 |
+
def __init__(self, **kwargs: Any) -> None:
|
| 12 |
+
for key, value in kwargs.items():
|
| 13 |
+
setattr(self, key, value)
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
class QyrouArchConfig(PretrainedConfig):
|
| 17 |
+
model_type = "qyrou_arch"
|
| 18 |
+
|
| 19 |
+
def __init__(
|
| 20 |
+
self,
|
| 21 |
+
vocab_size: int = 20_000,
|
| 22 |
+
hidden_size: int = 512,
|
| 23 |
+
num_hidden_layers: int = 21,
|
| 24 |
+
num_attention_heads: int = 8,
|
| 25 |
+
num_key_value_heads: int = 2,
|
| 26 |
+
intermediate_size: int = 1_328,
|
| 27 |
+
conv_layers: list[int] | None = None,
|
| 28 |
+
conv_kernel_size: int = 7,
|
| 29 |
+
rope_theta: float = 10_000.0,
|
| 30 |
+
rms_norm_eps: float = 1e-5,
|
| 31 |
+
max_position_embeddings: int = 2_048,
|
| 32 |
+
initializer_range: float = 0.02,
|
| 33 |
+
residual_initializer_scale: float = 1.0 / (42.0**0.5),
|
| 34 |
+
tie_word_embeddings: bool = True,
|
| 35 |
+
qk_norm: bool = True,
|
| 36 |
+
attention_backend: str = "cudnn",
|
| 37 |
+
fused_qkv_projection: bool = True,
|
| 38 |
+
fused_gate_up_projection: bool = True,
|
| 39 |
+
liger_rms_norm: bool = True,
|
| 40 |
+
liger_swiglu: bool = True,
|
| 41 |
+
cut_cross_entropy: bool = True,
|
| 42 |
+
use_cache: bool = True,
|
| 43 |
+
eod_token_id: int = 4,
|
| 44 |
+
**kwargs: Any,
|
| 45 |
+
) -> None:
|
| 46 |
+
super().__init__(tie_word_embeddings=tie_word_embeddings, **kwargs)
|
| 47 |
+
if hidden_size % num_attention_heads:
|
| 48 |
+
raise ValueError("hidden_size must be divisible by num_attention_heads")
|
| 49 |
+
if num_attention_heads % num_key_value_heads:
|
| 50 |
+
raise ValueError("num_attention_heads must be divisible by num_key_value_heads")
|
| 51 |
+
conv_layers = conv_layers if conv_layers is not None else [4, 9, 14, 19]
|
| 52 |
+
if len(set(conv_layers)) != len(conv_layers) or not all(
|
| 53 |
+
1 <= layer <= num_hidden_layers for layer in conv_layers
|
| 54 |
+
):
|
| 55 |
+
raise ValueError("conv_layers must contain unique one-based layer indices")
|
| 56 |
+
self.vocab_size = vocab_size
|
| 57 |
+
self.hidden_size = hidden_size
|
| 58 |
+
self.num_hidden_layers = num_hidden_layers
|
| 59 |
+
self.num_attention_heads = num_attention_heads
|
| 60 |
+
self.num_key_value_heads = num_key_value_heads
|
| 61 |
+
self.intermediate_size = intermediate_size
|
| 62 |
+
self.conv_layers = conv_layers
|
| 63 |
+
self.conv_kernel_size = conv_kernel_size
|
| 64 |
+
self.rope_theta = rope_theta
|
| 65 |
+
self.rms_norm_eps = rms_norm_eps
|
| 66 |
+
self.max_position_embeddings = max_position_embeddings
|
| 67 |
+
self.initializer_range = initializer_range
|
| 68 |
+
self.residual_initializer_scale = residual_initializer_scale
|
| 69 |
+
self.qk_norm = qk_norm
|
| 70 |
+
self.attention_backend = attention_backend
|
| 71 |
+
self.fused_qkv_projection = fused_qkv_projection
|
| 72 |
+
self.fused_gate_up_projection = fused_gate_up_projection
|
| 73 |
+
self.liger_rms_norm = liger_rms_norm
|
| 74 |
+
self.liger_swiglu = liger_swiglu
|
| 75 |
+
self.cut_cross_entropy = cut_cross_entropy
|
| 76 |
+
self.use_cache = use_cache
|
| 77 |
+
self.eod_token_id = eod_token_id
|
| 78 |
+
self.hidden_act = "silu"
|
| 79 |
+
|
source/qyrou_arch/data.py
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
import bisect
|
| 4 |
+
import hashlib
|
| 5 |
+
import random
|
| 6 |
+
from dataclasses import dataclass
|
| 7 |
+
from pathlib import Path
|
| 8 |
+
from typing import Any
|
| 9 |
+
|
| 10 |
+
import numpy as np
|
| 11 |
+
import torch
|
| 12 |
+
|
| 13 |
+
from .io_utils import read_json
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
@dataclass
|
| 17 |
+
class Batch:
|
| 18 |
+
input_ids: torch.LongTensor
|
| 19 |
+
labels: torch.LongTensor
|
| 20 |
+
real_tokens: int
|
| 21 |
+
start_cursor: int
|
| 22 |
+
end_cursor: int
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
class PackedTokenStream:
|
| 26 |
+
"""Deterministic one-pass stream over shuffled contiguous token blocks."""
|
| 27 |
+
|
| 28 |
+
def __init__(
|
| 29 |
+
self,
|
| 30 |
+
manifest_path: str | Path,
|
| 31 |
+
sequence_length: int,
|
| 32 |
+
pad_token_id: int,
|
| 33 |
+
seed: int = 1337,
|
| 34 |
+
cursor: int = 0,
|
| 35 |
+
shuffle_block_tokens: int = 65_536,
|
| 36 |
+
) -> None:
|
| 37 |
+
self.manifest_path = Path(manifest_path).resolve()
|
| 38 |
+
self.root = self.manifest_path.parent
|
| 39 |
+
self.manifest = read_json(self.manifest_path)
|
| 40 |
+
if not self.manifest.get("complete"):
|
| 41 |
+
raise RuntimeError("Token manifest is incomplete")
|
| 42 |
+
if self.manifest.get("dtype") != "uint16":
|
| 43 |
+
raise RuntimeError("Only uint16 token caches are supported")
|
| 44 |
+
self.sequence_length = sequence_length
|
| 45 |
+
self.pad_token_id = pad_token_id
|
| 46 |
+
self.seed = seed
|
| 47 |
+
if shuffle_block_tokens <= 0:
|
| 48 |
+
raise ValueError("shuffle_block_tokens must be positive")
|
| 49 |
+
if shuffle_block_tokens % sequence_length != 0:
|
| 50 |
+
raise ValueError("shuffle_block_tokens must be a multiple of sequence_length")
|
| 51 |
+
self.shuffle_block_tokens = shuffle_block_tokens
|
| 52 |
+
self.entries = list(self.manifest["shards"])
|
| 53 |
+
|
| 54 |
+
physical_blocks: list[tuple[int, int, int]] = []
|
| 55 |
+
for shard_index, entry in enumerate(self.entries):
|
| 56 |
+
shard_tokens = int(entry["tokens"])
|
| 57 |
+
for offset in range(0, shard_tokens, shuffle_block_tokens):
|
| 58 |
+
physical_blocks.append(
|
| 59 |
+
(shard_index, offset, min(shuffle_block_tokens, shard_tokens - offset))
|
| 60 |
+
)
|
| 61 |
+
permutation = list(range(len(physical_blocks)))
|
| 62 |
+
random.Random(seed).shuffle(permutation)
|
| 63 |
+
self.blocks = [physical_blocks[index] for index in permutation]
|
| 64 |
+
self.permutation = np.asarray(permutation, dtype=np.uint32)
|
| 65 |
+
self.permutation_sha256 = hashlib.sha256(self.permutation.tobytes()).hexdigest()
|
| 66 |
+
self.prefix = [0]
|
| 67 |
+
for _, _, block_length in self.blocks:
|
| 68 |
+
self.prefix.append(self.prefix[-1] + block_length)
|
| 69 |
+
self.total_tokens = self.prefix[-1]
|
| 70 |
+
self.cursor = 0
|
| 71 |
+
self._mapped_shard_index: int | None = None
|
| 72 |
+
self._mapped: np.memmap | None = None
|
| 73 |
+
self.seek(cursor)
|
| 74 |
+
|
| 75 |
+
@property
|
| 76 |
+
def remaining_tokens(self) -> int:
|
| 77 |
+
return self.total_tokens - self.cursor
|
| 78 |
+
|
| 79 |
+
@property
|
| 80 |
+
def current_block_index(self) -> int:
|
| 81 |
+
if not self.blocks:
|
| 82 |
+
return 0
|
| 83 |
+
position = min(self.cursor, self.total_tokens - 1)
|
| 84 |
+
return min(bisect.bisect_right(self.prefix, position) - 1, len(self.blocks) - 1)
|
| 85 |
+
|
| 86 |
+
@property
|
| 87 |
+
def current_shard_index(self) -> int:
|
| 88 |
+
if not self.blocks:
|
| 89 |
+
return 0
|
| 90 |
+
return self.blocks[self.current_block_index][0]
|
| 91 |
+
|
| 92 |
+
def state_dict(self) -> dict[str, Any]:
|
| 93 |
+
return {
|
| 94 |
+
"version": 2,
|
| 95 |
+
"cursor": self.cursor,
|
| 96 |
+
"seed": self.seed,
|
| 97 |
+
"shuffle_block_tokens": self.shuffle_block_tokens,
|
| 98 |
+
"block_count": len(self.blocks),
|
| 99 |
+
"permutation": self.permutation.copy(),
|
| 100 |
+
"permutation_sha256": self.permutation_sha256,
|
| 101 |
+
"manifest_tokenizer_sha256": self.manifest["tokenizer_sha256"],
|
| 102 |
+
"manifest_corpus_sha256": self.manifest["corpus_manifest_sha256"],
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
def load_state_dict(self, state: dict[str, Any]) -> None:
|
| 106 |
+
if state.get("version") != 2:
|
| 107 |
+
raise RuntimeError(
|
| 108 |
+
"Unsupported data-state version; old shard-only checkpoints cannot resume "
|
| 109 |
+
"the block-shuffled run"
|
| 110 |
+
)
|
| 111 |
+
if state.get("seed") != self.seed:
|
| 112 |
+
raise RuntimeError("Data shuffle seed does not match checkpoint")
|
| 113 |
+
if state.get("shuffle_block_tokens") != self.shuffle_block_tokens:
|
| 114 |
+
raise RuntimeError("Data shuffle block size does not match checkpoint")
|
| 115 |
+
if int(state.get("block_count", -1)) != len(self.blocks):
|
| 116 |
+
raise RuntimeError("Data shuffle block count does not match checkpoint")
|
| 117 |
+
checkpoint_permutation = np.asarray(state.get("permutation"), dtype=np.uint32)
|
| 118 |
+
checkpoint_hash = hashlib.sha256(checkpoint_permutation.tobytes()).hexdigest()
|
| 119 |
+
if (
|
| 120 |
+
checkpoint_permutation.shape != self.permutation.shape
|
| 121 |
+
or not np.array_equal(checkpoint_permutation, self.permutation)
|
| 122 |
+
or checkpoint_hash != state.get("permutation_sha256")
|
| 123 |
+
or checkpoint_hash != self.permutation_sha256
|
| 124 |
+
):
|
| 125 |
+
raise RuntimeError("Data block permutation does not match checkpoint")
|
| 126 |
+
if state.get("manifest_tokenizer_sha256") != self.manifest["tokenizer_sha256"]:
|
| 127 |
+
raise RuntimeError("Checkpoint tokenizer hash does not match token cache")
|
| 128 |
+
if state.get("manifest_corpus_sha256") != self.manifest["corpus_manifest_sha256"]:
|
| 129 |
+
raise RuntimeError("Checkpoint corpus hash does not match token cache")
|
| 130 |
+
self.seek(int(state["cursor"]))
|
| 131 |
+
|
| 132 |
+
def seek(self, cursor: int) -> None:
|
| 133 |
+
if not 0 <= cursor <= self.total_tokens:
|
| 134 |
+
raise ValueError(f"Cursor {cursor} is outside [0, {self.total_tokens}]")
|
| 135 |
+
self.cursor = cursor
|
| 136 |
+
|
| 137 |
+
def _map_block(self, logical_index: int) -> tuple[np.memmap, int, int]:
|
| 138 |
+
block_index = bisect.bisect_right(self.prefix, logical_index) - 1
|
| 139 |
+
if block_index >= len(self.blocks):
|
| 140 |
+
raise EOFError
|
| 141 |
+
shard_index, block_offset, _ = self.blocks[block_index]
|
| 142 |
+
if self._mapped_shard_index != shard_index:
|
| 143 |
+
self._mapped = np.memmap(
|
| 144 |
+
self.root / self.entries[shard_index]["file"],
|
| 145 |
+
mode="r",
|
| 146 |
+
dtype="<u2",
|
| 147 |
+
)
|
| 148 |
+
self._mapped_shard_index = shard_index
|
| 149 |
+
assert self._mapped is not None
|
| 150 |
+
offset = block_offset + logical_index - self.prefix[block_index]
|
| 151 |
+
available = self.prefix[block_index + 1] - logical_index
|
| 152 |
+
return self._mapped, offset, available
|
| 153 |
+
|
| 154 |
+
def read_tokens(self, count: int) -> np.ndarray:
|
| 155 |
+
if count < 0:
|
| 156 |
+
raise ValueError("count must be non-negative")
|
| 157 |
+
count = min(count, self.remaining_tokens)
|
| 158 |
+
result = np.empty(count, dtype=np.uint16)
|
| 159 |
+
written = 0
|
| 160 |
+
while written < count:
|
| 161 |
+
mapped, offset, available = self._map_block(self.cursor)
|
| 162 |
+
take = min(count - written, available)
|
| 163 |
+
result[written : written + take] = mapped[offset : offset + take]
|
| 164 |
+
self.cursor += take
|
| 165 |
+
written += take
|
| 166 |
+
return result
|
| 167 |
+
|
| 168 |
+
def next_batch(self, batch_size: int, device: torch.device | str) -> Batch | None:
|
| 169 |
+
if self.remaining_tokens <= 0:
|
| 170 |
+
return None
|
| 171 |
+
requested = batch_size * self.sequence_length
|
| 172 |
+
start = self.cursor
|
| 173 |
+
tokens = self.read_tokens(requested)
|
| 174 |
+
real_tokens = int(tokens.size)
|
| 175 |
+
if real_tokens < requested:
|
| 176 |
+
padded = np.full(requested, self.pad_token_id, dtype=np.uint16)
|
| 177 |
+
padded[:real_tokens] = tokens
|
| 178 |
+
tokens = padded
|
| 179 |
+
tensor = torch.from_numpy(tokens.astype(np.int64, copy=False)).view(
|
| 180 |
+
batch_size,
|
| 181 |
+
self.sequence_length,
|
| 182 |
+
)
|
| 183 |
+
labels = tensor.clone()
|
| 184 |
+
if real_tokens < requested:
|
| 185 |
+
labels.view(-1)[real_tokens:] = -100
|
| 186 |
+
return Batch(
|
| 187 |
+
input_ids=tensor.to(device, non_blocking=True),
|
| 188 |
+
labels=labels.to(device, non_blocking=True),
|
| 189 |
+
real_tokens=real_tokens,
|
| 190 |
+
start_cursor=start,
|
| 191 |
+
end_cursor=self.cursor,
|
| 192 |
+
)
|
| 193 |
+
|
| 194 |
+
|
| 195 |
+
class EvaluationTokens:
|
| 196 |
+
def __init__(self, path: str | Path, sequence_length: int, pad_token_id: int) -> None:
|
| 197 |
+
self.path = Path(path)
|
| 198 |
+
self.sequence_length = sequence_length
|
| 199 |
+
self.pad_token_id = pad_token_id
|
| 200 |
+
self.tokens = np.memmap(self.path, mode="r", dtype="<u2")
|
| 201 |
+
|
| 202 |
+
def batches(self, batch_size: int, device: torch.device | str, max_tokens: int):
|
| 203 |
+
usable = min(len(self.tokens), max_tokens)
|
| 204 |
+
cursor = 0
|
| 205 |
+
while cursor < usable:
|
| 206 |
+
requested = batch_size * self.sequence_length
|
| 207 |
+
take = min(requested, usable - cursor)
|
| 208 |
+
values = np.full(requested, self.pad_token_id, dtype=np.int64)
|
| 209 |
+
values[:take] = self.tokens[cursor : cursor + take]
|
| 210 |
+
input_ids = torch.from_numpy(values).view(batch_size, self.sequence_length)
|
| 211 |
+
labels = input_ids.clone()
|
| 212 |
+
labels.view(-1)[take:] = -100
|
| 213 |
+
yield input_ids.to(device), labels.to(device), take
|
| 214 |
+
cursor += take
|
source/qyrou_arch/io_utils.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
import hashlib
|
| 4 |
+
import json
|
| 5 |
+
import os
|
| 6 |
+
from pathlib import Path
|
| 7 |
+
from typing import Any
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
def sha256_file(path: Path, chunk_size: int = 8 * 1024 * 1024) -> str:
|
| 11 |
+
digest = hashlib.sha256()
|
| 12 |
+
with path.open("rb") as handle:
|
| 13 |
+
while chunk := handle.read(chunk_size):
|
| 14 |
+
digest.update(chunk)
|
| 15 |
+
return digest.hexdigest()
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
def sha256_json(value: Any) -> str:
|
| 19 |
+
payload = json.dumps(value, sort_keys=True, separators=(",", ":"), ensure_ascii=False)
|
| 20 |
+
return hashlib.sha256(payload.encode("utf-8")).hexdigest()
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def atomic_write_json(path: Path, value: Any) -> None:
|
| 24 |
+
path.parent.mkdir(parents=True, exist_ok=True)
|
| 25 |
+
temporary = path.with_name(f".{path.name}.tmp")
|
| 26 |
+
with temporary.open("w", encoding="utf-8", newline="\n") as handle:
|
| 27 |
+
json.dump(value, handle, ensure_ascii=False, indent=2)
|
| 28 |
+
handle.write("\n")
|
| 29 |
+
handle.flush()
|
| 30 |
+
os.fsync(handle.fileno())
|
| 31 |
+
os.replace(temporary, path)
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
def read_json(path: Path) -> Any:
|
| 35 |
+
with path.open("r", encoding="utf-8") as handle:
|
| 36 |
+
return json.load(handle)
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def load_run_config(path: str | Path) -> dict[str, Any]:
|
| 40 |
+
return read_json(Path(path).resolve())
|
| 41 |
+
|
source/qyrou_arch/metrics.py
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
import json
|
| 4 |
+
import math
|
| 5 |
+
import os
|
| 6 |
+
import subprocess
|
| 7 |
+
import time
|
| 8 |
+
from collections import deque
|
| 9 |
+
from pathlib import Path
|
| 10 |
+
from statistics import median
|
| 11 |
+
from typing import Any
|
| 12 |
+
|
| 13 |
+
import psutil
|
| 14 |
+
import torch
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
class RunningMetrics:
|
| 18 |
+
def __init__(self) -> None:
|
| 19 |
+
self.losses_100: deque[float] = deque(maxlen=100)
|
| 20 |
+
self.losses_1000: deque[float] = deque(maxlen=1000)
|
| 21 |
+
self.throughputs: deque[float] = deque(maxlen=5000)
|
| 22 |
+
self.spike_steps = 0
|
| 23 |
+
|
| 24 |
+
def update(self, loss: float, tps: float) -> None:
|
| 25 |
+
self.losses_100.append(loss)
|
| 26 |
+
self.losses_1000.append(loss)
|
| 27 |
+
self.throughputs.append(tps)
|
| 28 |
+
if len(self.losses_1000) == self.losses_1000.maxlen and self.ema_100 > 1.1 * self.ema_1000:
|
| 29 |
+
self.spike_steps += 1
|
| 30 |
+
else:
|
| 31 |
+
self.spike_steps = 0
|
| 32 |
+
|
| 33 |
+
@property
|
| 34 |
+
def ema_100(self) -> float:
|
| 35 |
+
return sum(self.losses_100) / max(len(self.losses_100), 1)
|
| 36 |
+
|
| 37 |
+
@property
|
| 38 |
+
def ema_1000(self) -> float:
|
| 39 |
+
return sum(self.losses_1000) / max(len(self.losses_1000), 1)
|
| 40 |
+
|
| 41 |
+
@property
|
| 42 |
+
def median_tps(self) -> float:
|
| 43 |
+
return median(self.throughputs) if self.throughputs else 0.0
|
| 44 |
+
|
| 45 |
+
def state_dict(self) -> dict[str, Any]:
|
| 46 |
+
return {
|
| 47 |
+
"losses_100": list(self.losses_100),
|
| 48 |
+
"losses_1000": list(self.losses_1000),
|
| 49 |
+
"throughputs": list(self.throughputs),
|
| 50 |
+
"spike_steps": self.spike_steps,
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
def load_state_dict(self, state: dict[str, Any]) -> None:
|
| 54 |
+
self.losses_100.extend(state.get("losses_100", []))
|
| 55 |
+
self.losses_1000.extend(state.get("losses_1000", []))
|
| 56 |
+
self.throughputs.extend(state.get("throughputs", []))
|
| 57 |
+
self.spike_steps = int(state.get("spike_steps", 0))
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
class JsonlLogger:
|
| 61 |
+
def __init__(self, path: str | Path) -> None:
|
| 62 |
+
self.path = Path(path)
|
| 63 |
+
self.path.parent.mkdir(parents=True, exist_ok=True)
|
| 64 |
+
|
| 65 |
+
def log(self, payload: dict[str, Any]) -> None:
|
| 66 |
+
payload = dict(payload)
|
| 67 |
+
payload.setdefault("wall_time", time.time())
|
| 68 |
+
with self.path.open("a", encoding="utf-8", newline="\n") as handle:
|
| 69 |
+
handle.write(json.dumps(payload, ensure_ascii=False) + "\n")
|
| 70 |
+
handle.flush()
|
| 71 |
+
os.fsync(handle.fileno())
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
def gpu_telemetry() -> dict[str, float | None]:
|
| 75 |
+
result: dict[str, float | None] = {
|
| 76 |
+
"gpu_temperature_c": None,
|
| 77 |
+
"gpu_power_w": None,
|
| 78 |
+
"gpu_util_percent": None,
|
| 79 |
+
}
|
| 80 |
+
try:
|
| 81 |
+
output = subprocess.check_output(
|
| 82 |
+
[
|
| 83 |
+
"nvidia-smi",
|
| 84 |
+
"--query-gpu=temperature.gpu,power.draw,utilization.gpu",
|
| 85 |
+
"--format=csv,noheader,nounits",
|
| 86 |
+
],
|
| 87 |
+
text=True,
|
| 88 |
+
timeout=3,
|
| 89 |
+
).strip()
|
| 90 |
+
temperature, power, utilization = (float(value.strip()) for value in output.split(","))
|
| 91 |
+
result.update(
|
| 92 |
+
{
|
| 93 |
+
"gpu_temperature_c": temperature,
|
| 94 |
+
"gpu_power_w": power,
|
| 95 |
+
"gpu_util_percent": utilization,
|
| 96 |
+
}
|
| 97 |
+
)
|
| 98 |
+
except (OSError, subprocess.SubprocessError, ValueError):
|
| 99 |
+
pass
|
| 100 |
+
return result
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
def system_telemetry() -> dict[str, float | None]:
|
| 104 |
+
process = psutil.Process()
|
| 105 |
+
payload: dict[str, float | None] = {
|
| 106 |
+
"process_ram_gib": process.memory_info().rss / 2**30,
|
| 107 |
+
"system_ram_percent": psutil.virtual_memory().percent,
|
| 108 |
+
}
|
| 109 |
+
if torch.cuda.is_available():
|
| 110 |
+
payload.update(
|
| 111 |
+
{
|
| 112 |
+
"gpu_allocated_gib": torch.cuda.memory_allocated() / 2**30,
|
| 113 |
+
"gpu_reserved_gib": torch.cuda.memory_reserved() / 2**30,
|
| 114 |
+
"gpu_peak_gib": torch.cuda.max_memory_allocated() / 2**30,
|
| 115 |
+
}
|
| 116 |
+
)
|
| 117 |
+
payload.update(gpu_telemetry())
|
| 118 |
+
return payload
|
| 119 |
+
|
| 120 |
+
|
| 121 |
+
def safe_perplexity(loss: float) -> float:
|
| 122 |
+
return math.exp(min(loss, 80.0))
|
source/qyrou_arch/modeling_qyrou_arch.py
ADDED
|
@@ -0,0 +1,504 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from typing import Any
|
| 4 |
+
|
| 5 |
+
import torch
|
| 6 |
+
import torch.nn as nn
|
| 7 |
+
import torch.nn.functional as F
|
| 8 |
+
from torch.nn.attention import SDPBackend, sdpa_kernel
|
| 9 |
+
from transformers import PreTrainedModel
|
| 10 |
+
from transformers.generation import GenerationMixin
|
| 11 |
+
from transformers.modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast
|
| 12 |
+
|
| 13 |
+
from .cache import QyrouArchHybridCache
|
| 14 |
+
from .configuration_qyrou_arch import QyrouArchConfig
|
| 15 |
+
|
| 16 |
+
try:
|
| 17 |
+
from .triton_kernels import PackedSwiGLUFunction
|
| 18 |
+
except (ImportError, RuntimeError):
|
| 19 |
+
PackedSwiGLUFunction = None
|
| 20 |
+
|
| 21 |
+
try:
|
| 22 |
+
from liger_kernel.ops.rms_norm import LigerRMSNormFunction
|
| 23 |
+
from liger_kernel.ops.swiglu import LigerSiLUMulFunction
|
| 24 |
+
except ImportError:
|
| 25 |
+
LigerRMSNormFunction = None
|
| 26 |
+
LigerSiLUMulFunction = None
|
| 27 |
+
|
| 28 |
+
try:
|
| 29 |
+
from cut_cross_entropy import linear_cross_entropy as cut_linear_cross_entropy
|
| 30 |
+
except ImportError:
|
| 31 |
+
cut_linear_cross_entropy = None
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
class RMSNorm(nn.Module):
|
| 35 |
+
def __init__(self, dim: int, eps: float, use_liger: bool = False) -> None:
|
| 36 |
+
super().__init__()
|
| 37 |
+
self.weight = nn.Parameter(torch.ones(dim))
|
| 38 |
+
self.eps = eps
|
| 39 |
+
self.use_liger = use_liger
|
| 40 |
+
|
| 41 |
+
def forward(self, x: torch.Tensor) -> torch.Tensor:
|
| 42 |
+
if (
|
| 43 |
+
x.is_cuda
|
| 44 |
+
and self.use_liger
|
| 45 |
+
and LigerRMSNormFunction is not None
|
| 46 |
+
and not torch.compiler.is_compiling()
|
| 47 |
+
):
|
| 48 |
+
return LigerRMSNormFunction.apply(x, self.weight, self.eps, 0.0, "llama", False, None)
|
| 49 |
+
x_float = x.float()
|
| 50 |
+
normalized = x_float * torch.rsqrt(x_float.square().mean(-1, keepdim=True) + self.eps)
|
| 51 |
+
return normalized.to(x.dtype) * self.weight.to(x.dtype)
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
def _apply_rope(
|
| 55 |
+
x: torch.Tensor,
|
| 56 |
+
cos: torch.Tensor,
|
| 57 |
+
sin: torch.Tensor,
|
| 58 |
+
) -> torch.Tensor:
|
| 59 |
+
even, odd = x[..., 0::2], x[..., 1::2]
|
| 60 |
+
return torch.stack((even * cos - odd * sin, even * sin + odd * cos), dim=-1).flatten(-2)
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def _last_valid_state(
|
| 64 |
+
x: torch.Tensor,
|
| 65 |
+
mask: torch.Tensor | None,
|
| 66 |
+
state_length: int,
|
| 67 |
+
) -> torch.Tensor:
|
| 68 |
+
if state_length == 0:
|
| 69 |
+
return x[:, :0]
|
| 70 |
+
if mask is None:
|
| 71 |
+
return F.pad(x, (0, 0, max(0, state_length - x.shape[1]), 0))[:, -state_length:]
|
| 72 |
+
result = torch.zeros(
|
| 73 |
+
(x.shape[0], state_length, x.shape[2]),
|
| 74 |
+
dtype=x.dtype,
|
| 75 |
+
device=x.device,
|
| 76 |
+
)
|
| 77 |
+
for batch_index in range(x.shape[0]):
|
| 78 |
+
valid = x[batch_index][mask[batch_index].bool()]
|
| 79 |
+
valid = valid[-state_length:]
|
| 80 |
+
result[batch_index, -valid.shape[0] :] = valid
|
| 81 |
+
return result
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
class CausalGQA(nn.Module):
|
| 85 |
+
def __init__(self, config: QyrouArchConfig, layer_idx: int) -> None:
|
| 86 |
+
super().__init__()
|
| 87 |
+
self.layer_idx = layer_idx
|
| 88 |
+
self.num_heads = config.num_attention_heads
|
| 89 |
+
self.num_kv_heads = config.num_key_value_heads
|
| 90 |
+
self.head_dim = config.hidden_size // config.num_attention_heads
|
| 91 |
+
self.q_size = self.num_heads * self.head_dim
|
| 92 |
+
self.kv_size = self.num_kv_heads * self.head_dim
|
| 93 |
+
self.attention_backend = config.attention_backend
|
| 94 |
+
if config.fused_qkv_projection:
|
| 95 |
+
self.qkv_proj = nn.Linear(config.hidden_size, self.q_size + 2 * self.kv_size, bias=False)
|
| 96 |
+
else:
|
| 97 |
+
self.q_proj = nn.Linear(config.hidden_size, self.q_size, bias=False)
|
| 98 |
+
self.k_proj = nn.Linear(config.hidden_size, self.kv_size, bias=False)
|
| 99 |
+
self.v_proj = nn.Linear(config.hidden_size, self.kv_size, bias=False)
|
| 100 |
+
self.o_proj = nn.Linear(config.hidden_size, config.hidden_size, bias=False)
|
| 101 |
+
self.o_proj._qyrou_arch_residual_projection = True # type: ignore[attr-defined]
|
| 102 |
+
self.q_norm = RMSNorm(self.head_dim, config.rms_norm_eps) if config.qk_norm else nn.Identity()
|
| 103 |
+
self.k_norm = RMSNorm(self.head_dim, config.rms_norm_eps) if config.qk_norm else nn.Identity()
|
| 104 |
+
|
| 105 |
+
def forward(
|
| 106 |
+
self,
|
| 107 |
+
x: torch.Tensor,
|
| 108 |
+
rope: tuple[torch.Tensor, torch.Tensor],
|
| 109 |
+
attention_mask: torch.Tensor | None,
|
| 110 |
+
cache: QyrouArchHybridCache | None,
|
| 111 |
+
cache_position: torch.Tensor,
|
| 112 |
+
) -> torch.Tensor:
|
| 113 |
+
batch, query_length, _ = x.shape
|
| 114 |
+
if hasattr(self, "qkv_proj"):
|
| 115 |
+
q, k, v = self.qkv_proj(x).split((self.q_size, self.kv_size, self.kv_size), dim=-1)
|
| 116 |
+
else:
|
| 117 |
+
q, k, v = self.q_proj(x), self.k_proj(x), self.v_proj(x)
|
| 118 |
+
q = q.view(batch, query_length, self.num_heads, self.head_dim).transpose(1, 2)
|
| 119 |
+
k = k.view(batch, query_length, self.num_kv_heads, self.head_dim).transpose(1, 2)
|
| 120 |
+
v = v.view(batch, query_length, self.num_kv_heads, self.head_dim).transpose(1, 2)
|
| 121 |
+
q, k = self.q_norm(q), self.k_norm(k)
|
| 122 |
+
q = _apply_rope(q, *rope)
|
| 123 |
+
k = _apply_rope(k, *rope)
|
| 124 |
+
if cache is not None:
|
| 125 |
+
k, v = cache.update_attention(self.layer_idx, k, v, cache_position)
|
| 126 |
+
key_length = k.shape[2]
|
| 127 |
+
|
| 128 |
+
mask = None
|
| 129 |
+
use_fast_causal = cache is None and attention_mask is None
|
| 130 |
+
if not use_fast_causal:
|
| 131 |
+
key_positions = torch.arange(key_length, device=x.device)
|
| 132 |
+
allowed = key_positions[None, :] <= cache_position[:, None]
|
| 133 |
+
mask = allowed[None, None, :, :].expand(batch, 1, query_length, key_length)
|
| 134 |
+
if attention_mask is not None:
|
| 135 |
+
if attention_mask.shape[-1] < key_length:
|
| 136 |
+
raise ValueError("attention_mask is shorter than the cached key sequence")
|
| 137 |
+
mask = mask & attention_mask[:, None, None, :key_length].bool()
|
| 138 |
+
if q.is_cuda and self.attention_backend in {"cudnn", "flash"}:
|
| 139 |
+
backends = (
|
| 140 |
+
[SDPBackend.CUDNN_ATTENTION, SDPBackend.FLASH_ATTENTION, SDPBackend.MATH]
|
| 141 |
+
if self.attention_backend == "cudnn"
|
| 142 |
+
else [SDPBackend.FLASH_ATTENTION, SDPBackend.CUDNN_ATTENTION, SDPBackend.MATH]
|
| 143 |
+
)
|
| 144 |
+
with sdpa_kernel(
|
| 145 |
+
backends,
|
| 146 |
+
set_priority=True,
|
| 147 |
+
):
|
| 148 |
+
output = F.scaled_dot_product_attention(
|
| 149 |
+
q,
|
| 150 |
+
k,
|
| 151 |
+
v,
|
| 152 |
+
attn_mask=mask,
|
| 153 |
+
is_causal=use_fast_causal,
|
| 154 |
+
enable_gqa=True,
|
| 155 |
+
)
|
| 156 |
+
else:
|
| 157 |
+
output = F.scaled_dot_product_attention(
|
| 158 |
+
q,
|
| 159 |
+
k,
|
| 160 |
+
v,
|
| 161 |
+
attn_mask=mask,
|
| 162 |
+
is_causal=use_fast_causal,
|
| 163 |
+
enable_gqa=True,
|
| 164 |
+
)
|
| 165 |
+
output = output.transpose(1, 2).contiguous().view(batch, query_length, -1)
|
| 166 |
+
return self.o_proj(output)
|
| 167 |
+
|
| 168 |
+
|
| 169 |
+
class CausalConvMixer(nn.Module):
|
| 170 |
+
def __init__(self, config: QyrouArchConfig, layer_idx: int) -> None:
|
| 171 |
+
super().__init__()
|
| 172 |
+
self.layer_idx = layer_idx
|
| 173 |
+
self.kernel_size = config.conv_kernel_size
|
| 174 |
+
self.depthwise = nn.Conv1d(
|
| 175 |
+
config.hidden_size,
|
| 176 |
+
config.hidden_size,
|
| 177 |
+
kernel_size=self.kernel_size,
|
| 178 |
+
groups=config.hidden_size,
|
| 179 |
+
bias=False,
|
| 180 |
+
)
|
| 181 |
+
self.pointwise = nn.Linear(config.hidden_size, config.hidden_size, bias=False)
|
| 182 |
+
self.pointwise._qyrou_arch_residual_projection = True # type: ignore[attr-defined]
|
| 183 |
+
|
| 184 |
+
def forward(
|
| 185 |
+
self,
|
| 186 |
+
x: torch.Tensor,
|
| 187 |
+
_rope: tuple[torch.Tensor, torch.Tensor],
|
| 188 |
+
attention_mask: torch.Tensor | None,
|
| 189 |
+
cache: QyrouArchHybridCache | None,
|
| 190 |
+
_cache_position: torch.Tensor,
|
| 191 |
+
) -> torch.Tensor:
|
| 192 |
+
state_length = self.kernel_size - 1
|
| 193 |
+
query_mask = attention_mask[:, -x.shape[1] :] if attention_mask is not None else None
|
| 194 |
+
if query_mask is not None:
|
| 195 |
+
x = x * query_mask.unsqueeze(-1).to(x.dtype)
|
| 196 |
+
if cache is None:
|
| 197 |
+
conv_input = F.pad(x.transpose(1, 2), (state_length, 0))
|
| 198 |
+
else:
|
| 199 |
+
previous = cache.get_convolution(self.layer_idx)
|
| 200 |
+
if previous is None:
|
| 201 |
+
previous = torch.zeros(
|
| 202 |
+
(x.shape[0], state_length, x.shape[2]),
|
| 203 |
+
dtype=x.dtype,
|
| 204 |
+
device=x.device,
|
| 205 |
+
)
|
| 206 |
+
combined = torch.cat((previous, x), dim=1)
|
| 207 |
+
conv_input = combined.transpose(1, 2)
|
| 208 |
+
combined_mask = None
|
| 209 |
+
if query_mask is not None:
|
| 210 |
+
combined_mask = torch.cat(
|
| 211 |
+
(
|
| 212 |
+
torch.ones(
|
| 213 |
+
(x.shape[0], state_length),
|
| 214 |
+
dtype=query_mask.dtype,
|
| 215 |
+
device=query_mask.device,
|
| 216 |
+
),
|
| 217 |
+
query_mask,
|
| 218 |
+
),
|
| 219 |
+
dim=1,
|
| 220 |
+
)
|
| 221 |
+
cache.update_convolution(
|
| 222 |
+
self.layer_idx,
|
| 223 |
+
_last_valid_state(combined, combined_mask, state_length),
|
| 224 |
+
)
|
| 225 |
+
return self.pointwise(self.depthwise(conv_input).transpose(1, 2))
|
| 226 |
+
|
| 227 |
+
|
| 228 |
+
class SwiGLU(nn.Module):
|
| 229 |
+
def __init__(self, config: QyrouArchConfig) -> None:
|
| 230 |
+
super().__init__()
|
| 231 |
+
self.intermediate_size = config.intermediate_size
|
| 232 |
+
self.use_liger = config.liger_swiglu
|
| 233 |
+
if config.fused_gate_up_projection:
|
| 234 |
+
self.gate_up_proj = nn.Linear(config.hidden_size, 2 * config.intermediate_size, bias=False)
|
| 235 |
+
else:
|
| 236 |
+
self.gate_proj = nn.Linear(config.hidden_size, config.intermediate_size, bias=False)
|
| 237 |
+
self.up_proj = nn.Linear(config.hidden_size, config.intermediate_size, bias=False)
|
| 238 |
+
self.down_proj = nn.Linear(config.intermediate_size, config.hidden_size, bias=False)
|
| 239 |
+
self.down_proj._qyrou_arch_residual_projection = True # type: ignore[attr-defined]
|
| 240 |
+
|
| 241 |
+
def forward(self, x: torch.Tensor) -> torch.Tensor:
|
| 242 |
+
if hasattr(self, "gate_up_proj"):
|
| 243 |
+
packed = self.gate_up_proj(x)
|
| 244 |
+
if (
|
| 245 |
+
packed.is_cuda
|
| 246 |
+
and self.use_liger
|
| 247 |
+
and PackedSwiGLUFunction is not None
|
| 248 |
+
and not torch.compiler.is_compiling()
|
| 249 |
+
):
|
| 250 |
+
return self.down_proj(PackedSwiGLUFunction.apply(packed))
|
| 251 |
+
gate, up = packed.chunk(2, dim=-1)
|
| 252 |
+
else:
|
| 253 |
+
gate, up = self.gate_proj(x), self.up_proj(x)
|
| 254 |
+
if torch.compiler.is_compiling():
|
| 255 |
+
activated = F.silu(gate) * up
|
| 256 |
+
elif x.is_cuda and self.use_liger and LigerSiLUMulFunction is not None:
|
| 257 |
+
activated = LigerSiLUMulFunction.apply(gate, up, 1.0, 1.0)
|
| 258 |
+
else:
|
| 259 |
+
activated = F.silu(gate) * up
|
| 260 |
+
return self.down_proj(activated)
|
| 261 |
+
|
| 262 |
+
|
| 263 |
+
class QyrouArchBlock(nn.Module):
|
| 264 |
+
def __init__(self, config: QyrouArchConfig, layer_idx: int) -> None:
|
| 265 |
+
super().__init__()
|
| 266 |
+
self.mixer_norm = RMSNorm(config.hidden_size, config.rms_norm_eps, config.liger_rms_norm)
|
| 267 |
+
self.ffn_norm = RMSNorm(config.hidden_size, config.rms_norm_eps, config.liger_rms_norm)
|
| 268 |
+
layer_number = layer_idx + 1
|
| 269 |
+
self.mixer = (
|
| 270 |
+
CausalConvMixer(config, layer_idx)
|
| 271 |
+
if layer_number in config.conv_layers
|
| 272 |
+
else CausalGQA(config, layer_idx)
|
| 273 |
+
)
|
| 274 |
+
self.ffn = SwiGLU(config)
|
| 275 |
+
|
| 276 |
+
def forward(
|
| 277 |
+
self,
|
| 278 |
+
x: torch.Tensor,
|
| 279 |
+
rope: tuple[torch.Tensor, torch.Tensor],
|
| 280 |
+
attention_mask: torch.Tensor | None,
|
| 281 |
+
cache: QyrouArchHybridCache | None,
|
| 282 |
+
cache_position: torch.Tensor,
|
| 283 |
+
) -> torch.Tensor:
|
| 284 |
+
x = x + self.mixer(self.mixer_norm(x), rope, attention_mask, cache, cache_position)
|
| 285 |
+
return x + self.ffn(self.ffn_norm(x))
|
| 286 |
+
|
| 287 |
+
|
| 288 |
+
class QyrouArchPreTrainedModel(PreTrainedModel):
|
| 289 |
+
config_class = QyrouArchConfig
|
| 290 |
+
base_model_prefix = "model"
|
| 291 |
+
supports_gradient_checkpointing = False
|
| 292 |
+
_no_split_modules = ["QyrouArchBlock"]
|
| 293 |
+
|
| 294 |
+
def _init_weights(self, module: nn.Module) -> None:
|
| 295 |
+
if isinstance(module, (nn.Linear, nn.Embedding, nn.Conv1d)):
|
| 296 |
+
scale = (
|
| 297 |
+
self.config.residual_initializer_scale
|
| 298 |
+
if getattr(module, "_qyrou_arch_residual_projection", False)
|
| 299 |
+
else 1.0
|
| 300 |
+
)
|
| 301 |
+
nn.init.normal_(module.weight, mean=0.0, std=self.config.initializer_range * scale)
|
| 302 |
+
|
| 303 |
+
|
| 304 |
+
class QyrouArchModel(QyrouArchPreTrainedModel):
|
| 305 |
+
def __init__(self, config: QyrouArchConfig) -> None:
|
| 306 |
+
super().__init__(config)
|
| 307 |
+
self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size)
|
| 308 |
+
self.layers = nn.ModuleList(
|
| 309 |
+
[QyrouArchBlock(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
|
| 310 |
+
)
|
| 311 |
+
self.norm = RMSNorm(config.hidden_size, config.rms_norm_eps, config.liger_rms_norm)
|
| 312 |
+
head_dim = config.hidden_size // config.num_attention_heads
|
| 313 |
+
inv_freq = 1.0 / (
|
| 314 |
+
config.rope_theta ** (torch.arange(0, head_dim, 2).float() / head_dim)
|
| 315 |
+
)
|
| 316 |
+
positions = torch.arange(config.max_position_embeddings, dtype=torch.float32)
|
| 317 |
+
angles = torch.outer(positions, inv_freq)
|
| 318 |
+
self.register_buffer("rope_cos", angles.cos(), persistent=False)
|
| 319 |
+
self.register_buffer("rope_sin", angles.sin(), persistent=False)
|
| 320 |
+
self.post_init()
|
| 321 |
+
|
| 322 |
+
def _rope(
|
| 323 |
+
self,
|
| 324 |
+
position_ids: torch.Tensor,
|
| 325 |
+
dtype: torch.dtype,
|
| 326 |
+
) -> tuple[torch.Tensor, torch.Tensor]:
|
| 327 |
+
if (
|
| 328 |
+
not torch.compiler.is_compiling()
|
| 329 |
+
and int(position_ids.max()) >= self.config.max_position_embeddings
|
| 330 |
+
):
|
| 331 |
+
raise ValueError("Position exceeds max_position_embeddings")
|
| 332 |
+
cos = self.rope_cos[position_ids].to(dtype).unsqueeze(1)
|
| 333 |
+
sin = self.rope_sin[position_ids].to(dtype).unsqueeze(1)
|
| 334 |
+
return cos, sin
|
| 335 |
+
|
| 336 |
+
def forward(
|
| 337 |
+
self,
|
| 338 |
+
input_ids: torch.LongTensor | None = None,
|
| 339 |
+
attention_mask: torch.Tensor | None = None,
|
| 340 |
+
position_ids: torch.LongTensor | None = None,
|
| 341 |
+
past_key_values: QyrouArchHybridCache | None = None,
|
| 342 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 343 |
+
use_cache: bool | None = None,
|
| 344 |
+
cache_position: torch.LongTensor | None = None,
|
| 345 |
+
return_dict: bool | None = None,
|
| 346 |
+
**_: Any,
|
| 347 |
+
) -> BaseModelOutputWithPast | tuple[torch.Tensor, QyrouArchHybridCache | None]:
|
| 348 |
+
if (input_ids is None) == (inputs_embeds is None):
|
| 349 |
+
raise ValueError("Pass exactly one of input_ids or inputs_embeds")
|
| 350 |
+
hidden = self.embed_tokens(input_ids) if inputs_embeds is None else inputs_embeds
|
| 351 |
+
if hidden.is_cuda and torch.is_autocast_enabled("cuda"):
|
| 352 |
+
hidden = hidden.to(torch.get_autocast_dtype("cuda"))
|
| 353 |
+
batch, query_length, _ = hidden.shape
|
| 354 |
+
use_cache = self.config.use_cache if use_cache is None else use_cache
|
| 355 |
+
return_dict = self.config.return_dict if return_dict is None else return_dict
|
| 356 |
+
if use_cache and past_key_values is None:
|
| 357 |
+
past_key_values = QyrouArchHybridCache(self.config.num_hidden_layers)
|
| 358 |
+
cache = past_key_values if use_cache else None
|
| 359 |
+
past_length = cache.get_seq_length() if cache is not None else 0
|
| 360 |
+
if cache_position is None:
|
| 361 |
+
cache_position = torch.arange(
|
| 362 |
+
past_length,
|
| 363 |
+
past_length + query_length,
|
| 364 |
+
device=hidden.device,
|
| 365 |
+
)
|
| 366 |
+
if position_ids is None:
|
| 367 |
+
if attention_mask is not None:
|
| 368 |
+
position_ids = attention_mask.long().cumsum(-1).sub(1).clamp_min(0)[:, -query_length:]
|
| 369 |
+
else:
|
| 370 |
+
position_ids = cache_position.unsqueeze(0).expand(batch, -1)
|
| 371 |
+
rope = self._rope(position_ids, hidden.dtype)
|
| 372 |
+
for layer in self.layers:
|
| 373 |
+
hidden = layer(hidden, rope, attention_mask, cache, cache_position)
|
| 374 |
+
hidden = self.norm(hidden)
|
| 375 |
+
if cache is not None:
|
| 376 |
+
cache.finish_step(cache_position)
|
| 377 |
+
if not return_dict:
|
| 378 |
+
return hidden, cache
|
| 379 |
+
return BaseModelOutputWithPast(last_hidden_state=hidden, past_key_values=cache)
|
| 380 |
+
|
| 381 |
+
|
| 382 |
+
class QyrouArchForCausalLM(QyrouArchPreTrainedModel, GenerationMixin):
|
| 383 |
+
_tied_weights_keys = {"lm_head.weight": "model.embed_tokens.weight"}
|
| 384 |
+
|
| 385 |
+
def __init__(self, config: QyrouArchConfig) -> None:
|
| 386 |
+
super().__init__(config)
|
| 387 |
+
self.model = QyrouArchModel(config)
|
| 388 |
+
self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
|
| 389 |
+
self.post_init()
|
| 390 |
+
self.tie_weights()
|
| 391 |
+
|
| 392 |
+
def get_input_embeddings(self) -> nn.Module:
|
| 393 |
+
return self.model.embed_tokens
|
| 394 |
+
|
| 395 |
+
def set_input_embeddings(self, value: nn.Module) -> None:
|
| 396 |
+
self.model.embed_tokens = value
|
| 397 |
+
|
| 398 |
+
def get_output_embeddings(self) -> nn.Module:
|
| 399 |
+
return self.lm_head
|
| 400 |
+
|
| 401 |
+
def set_output_embeddings(self, value: nn.Module) -> None:
|
| 402 |
+
self.lm_head = value
|
| 403 |
+
|
| 404 |
+
def forward(
|
| 405 |
+
self,
|
| 406 |
+
input_ids: torch.LongTensor | None = None,
|
| 407 |
+
attention_mask: torch.Tensor | None = None,
|
| 408 |
+
position_ids: torch.LongTensor | None = None,
|
| 409 |
+
past_key_values: QyrouArchHybridCache | None = None,
|
| 410 |
+
inputs_embeds: torch.Tensor | None = None,
|
| 411 |
+
labels: torch.LongTensor | None = None,
|
| 412 |
+
use_cache: bool | None = None,
|
| 413 |
+
cache_position: torch.LongTensor | None = None,
|
| 414 |
+
return_logits: bool = True,
|
| 415 |
+
return_dict: bool | None = None,
|
| 416 |
+
**kwargs: Any,
|
| 417 |
+
) -> CausalLMOutputWithPast | tuple[Any, ...]:
|
| 418 |
+
return_dict = self.config.return_dict if return_dict is None else return_dict
|
| 419 |
+
outputs = self.model(
|
| 420 |
+
input_ids=input_ids,
|
| 421 |
+
attention_mask=attention_mask,
|
| 422 |
+
position_ids=position_ids,
|
| 423 |
+
past_key_values=past_key_values,
|
| 424 |
+
inputs_embeds=inputs_embeds,
|
| 425 |
+
use_cache=use_cache,
|
| 426 |
+
cache_position=cache_position,
|
| 427 |
+
return_dict=True,
|
| 428 |
+
**kwargs,
|
| 429 |
+
)
|
| 430 |
+
hidden = outputs.last_hidden_state
|
| 431 |
+
training_loss_only = labels is not None and not return_logits
|
| 432 |
+
logits = None if training_loss_only else self.lm_head(hidden)
|
| 433 |
+
loss = None
|
| 434 |
+
if labels is not None:
|
| 435 |
+
if (
|
| 436 |
+
training_loss_only
|
| 437 |
+
and hidden.is_cuda
|
| 438 |
+
and self.config.cut_cross_entropy
|
| 439 |
+
and cut_linear_cross_entropy is not None
|
| 440 |
+
):
|
| 441 |
+
loss = cut_linear_cross_entropy(
|
| 442 |
+
hidden,
|
| 443 |
+
self.lm_head.weight,
|
| 444 |
+
labels,
|
| 445 |
+
shift=True,
|
| 446 |
+
filter_eps=None,
|
| 447 |
+
)
|
| 448 |
+
else:
|
| 449 |
+
loss_logits = self.lm_head(hidden[:, :-1]).float()
|
| 450 |
+
loss = F.cross_entropy(
|
| 451 |
+
loss_logits.reshape(-1, self.config.vocab_size),
|
| 452 |
+
labels[:, 1:].contiguous().view(-1),
|
| 453 |
+
ignore_index=-100,
|
| 454 |
+
)
|
| 455 |
+
if not return_dict:
|
| 456 |
+
return loss, logits, outputs.past_key_values
|
| 457 |
+
return CausalLMOutputWithPast(
|
| 458 |
+
loss=loss,
|
| 459 |
+
logits=logits,
|
| 460 |
+
past_key_values=outputs.past_key_values,
|
| 461 |
+
)
|
| 462 |
+
|
| 463 |
+
def prepare_inputs_for_generation(
|
| 464 |
+
self,
|
| 465 |
+
input_ids: torch.LongTensor,
|
| 466 |
+
past_key_values: QyrouArchHybridCache | None = None,
|
| 467 |
+
attention_mask: torch.Tensor | None = None,
|
| 468 |
+
cache_position: torch.LongTensor | None = None,
|
| 469 |
+
use_cache: bool = True,
|
| 470 |
+
**kwargs: Any,
|
| 471 |
+
) -> dict[str, Any]:
|
| 472 |
+
past_length = past_key_values.get_seq_length() if past_key_values is not None else 0
|
| 473 |
+
if past_length:
|
| 474 |
+
input_ids = (
|
| 475 |
+
input_ids[:, past_length:]
|
| 476 |
+
if input_ids.shape[1] > past_length
|
| 477 |
+
else input_ids[:, -1:]
|
| 478 |
+
)
|
| 479 |
+
if cache_position is None:
|
| 480 |
+
cache_position = torch.arange(
|
| 481 |
+
past_length,
|
| 482 |
+
past_length + input_ids.shape[1],
|
| 483 |
+
device=input_ids.device,
|
| 484 |
+
)
|
| 485 |
+
elif cache_position.numel() != input_ids.shape[1]:
|
| 486 |
+
cache_position = cache_position[-input_ids.shape[1] :]
|
| 487 |
+
return {
|
| 488 |
+
"input_ids": input_ids,
|
| 489 |
+
"attention_mask": attention_mask,
|
| 490 |
+
"past_key_values": past_key_values,
|
| 491 |
+
"cache_position": cache_position,
|
| 492 |
+
"use_cache": use_cache,
|
| 493 |
+
}
|
| 494 |
+
|
| 495 |
+
def _reorder_cache(
|
| 496 |
+
self,
|
| 497 |
+
past_key_values: QyrouArchHybridCache,
|
| 498 |
+
beam_idx: torch.LongTensor,
|
| 499 |
+
) -> QyrouArchHybridCache:
|
| 500 |
+
return past_key_values.reorder_cache(beam_idx)
|
| 501 |
+
|
| 502 |
+
|
| 503 |
+
QyrouArchConfig.register_for_auto_class()
|
| 504 |
+
QyrouArchForCausalLM.register_for_auto_class("AutoModelForCausalLM")
|
source/qyrou_arch/tokenizer_markers.py
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from dataclasses import dataclass
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
@dataclass(frozen=True)
|
| 7 |
+
class Marker:
|
| 8 |
+
text: str
|
| 9 |
+
special: bool
|
| 10 |
+
category: str
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
def _markers(values: list[str], *, special: bool, category: str) -> list[Marker]:
|
| 14 |
+
return [Marker(value, special, category) for value in values]
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
MARKERS: list[Marker] = [
|
| 18 |
+
*_markers(
|
| 19 |
+
["<|bos|>", "<|eos|>", "<|pad|>", "<|unk|>", "<|eod|>"],
|
| 20 |
+
special=True,
|
| 21 |
+
category="core",
|
| 22 |
+
),
|
| 23 |
+
*_markers(
|
| 24 |
+
["<|startoftext|>", "<|endoftext|>", "<|endofprompt|>"],
|
| 25 |
+
special=True,
|
| 26 |
+
category="text_boundaries",
|
| 27 |
+
),
|
| 28 |
+
*_markers(
|
| 29 |
+
[
|
| 30 |
+
"<|im_start|>", "<|im_end|>", "<|system|>", "<|developer|>",
|
| 31 |
+
"<|user|>", "<|assistant|>", "<|tool|>", "<|function|>",
|
| 32 |
+
"<|observation|>", "<|eot|>",
|
| 33 |
+
],
|
| 34 |
+
special=True,
|
| 35 |
+
category="chatml",
|
| 36 |
+
),
|
| 37 |
+
*_markers(
|
| 38 |
+
[
|
| 39 |
+
"<think>", "</think>", "<analysis>", "</analysis>", "<reasoning>",
|
| 40 |
+
"</reasoning>", "<commentary>", "</commentary>", "<final>", "</final>",
|
| 41 |
+
],
|
| 42 |
+
special=False,
|
| 43 |
+
category="reasoning",
|
| 44 |
+
),
|
| 45 |
+
*_markers(
|
| 46 |
+
[
|
| 47 |
+
"<tools>", "</tools>", "<available_tools>", "</available_tools>",
|
| 48 |
+
"<tool_call>", "</tool_call>", "<tool_response>", "</tool_response>",
|
| 49 |
+
"<function_call>", "</function_call>", "<function_response>",
|
| 50 |
+
"</function_response>", "<|tool_sep|>",
|
| 51 |
+
],
|
| 52 |
+
special=False,
|
| 53 |
+
category="tools",
|
| 54 |
+
),
|
| 55 |
+
*_markers(
|
| 56 |
+
[
|
| 57 |
+
"<|fim_prefix|>", "<|fim_middle|>", "<|fim_suffix|>", "<|fim_pad|>",
|
| 58 |
+
"<|repo_name|>", "<|file_sep|>",
|
| 59 |
+
],
|
| 60 |
+
special=False,
|
| 61 |
+
category="qwen_fim",
|
| 62 |
+
),
|
| 63 |
+
*_markers(
|
| 64 |
+
[
|
| 65 |
+
"<fim_prefix>", "<fim_middle>", "<fim_suffix>", "<fim_pad>",
|
| 66 |
+
"<repo_name>", "<file_sep>", "<issue_start>", "<issue_comment>",
|
| 67 |
+
"<issue_closed>", "<jupyter_start>", "<jupyter_text>", "<jupyter_code>",
|
| 68 |
+
"<jupyter_output>", "<jupyter_script>", "<empty_output>",
|
| 69 |
+
],
|
| 70 |
+
special=False,
|
| 71 |
+
category="starcoder",
|
| 72 |
+
),
|
| 73 |
+
*_markers(
|
| 74 |
+
[
|
| 75 |
+
"<|begin_of_text|>", "<|end_of_text|>", "<|start_header_id|>",
|
| 76 |
+
"<|end_header_id|>", "<|eot_id|>", "<|eom_id|>", "<|python_tag|>",
|
| 77 |
+
],
|
| 78 |
+
special=True,
|
| 79 |
+
category="llama",
|
| 80 |
+
),
|
| 81 |
+
*_markers(
|
| 82 |
+
["<start_of_turn>", "<end_of_turn>", "<start_of_image>"],
|
| 83 |
+
special=True,
|
| 84 |
+
category="gemma",
|
| 85 |
+
),
|
| 86 |
+
*_markers(
|
| 87 |
+
[
|
| 88 |
+
"<s>", "</s>", "<unk>", "<pad>", "[INST]", "[/INST]",
|
| 89 |
+
"[AVAILABLE_TOOLS]", "[/AVAILABLE_TOOLS]", "[TOOL_CALLS]",
|
| 90 |
+
"[TOOL_RESULTS]", "[/TOOL_RESULTS]", "[SYSTEM_PROMPT]",
|
| 91 |
+
"[/SYSTEM_PROMPT]", "[TOOL_CONTENT]", "[ARGS]", "[CALL_ID]",
|
| 92 |
+
"[PREFIX]", "[MIDDLE]", "[SUFFIX]", "[THINK]", "[/THINK]",
|
| 93 |
+
"[MODEL_SETTINGS]", "[/MODEL_SETTINGS]",
|
| 94 |
+
],
|
| 95 |
+
special=True,
|
| 96 |
+
category="mistral",
|
| 97 |
+
),
|
| 98 |
+
*_markers(
|
| 99 |
+
[
|
| 100 |
+
"<|begin▁of▁sentence|>", "<|end▁of▁sentence|>", "<|User|>",
|
| 101 |
+
"<|Assistant|>", "<|tool▁calls▁begin|>", "<|tool▁call▁begin|>",
|
| 102 |
+
"<|tool▁sep|>", "<|tool▁call▁end|>", "<|tool▁calls▁end|>",
|
| 103 |
+
"<|tool▁outputs▁begin|>", "<|tool▁output▁begin|>",
|
| 104 |
+
"<|tool▁output▁end|>", "<|tool▁outputs▁end|>", "<|fim▁begin|>",
|
| 105 |
+
"<|fim▁hole|>", "<|fim▁end|>",
|
| 106 |
+
],
|
| 107 |
+
special=True,
|
| 108 |
+
category="deepseek",
|
| 109 |
+
),
|
| 110 |
+
*_markers(
|
| 111 |
+
["<|start|>", "<|end|>", "<|message|>", "<|channel|>", "<|constrain|>", "<|return|>", "<|call|>"],
|
| 112 |
+
special=True,
|
| 113 |
+
category="harmony",
|
| 114 |
+
),
|
| 115 |
+
*_markers(
|
| 116 |
+
[
|
| 117 |
+
"<|vision_start|>", "<|vision_end|>", "<|vision_pad|>", "<|image_pad|>",
|
| 118 |
+
"<|video_pad|>", "<|image|>", "<|video|>", "[IMG]", "[IMG_BREAK]",
|
| 119 |
+
"[IMG_END]",
|
| 120 |
+
],
|
| 121 |
+
special=True,
|
| 122 |
+
category="vision",
|
| 123 |
+
),
|
| 124 |
+
*_markers(
|
| 125 |
+
["<|audio_bos|>", "<|AUDIO|>", "<|audio_eos|>", "<|audio_pad|>", "[AUDIO]", "[BEGIN_AUDIO]"],
|
| 126 |
+
special=True,
|
| 127 |
+
category="audio",
|
| 128 |
+
),
|
| 129 |
+
]
|
| 130 |
+
|
| 131 |
+
RESERVED_MARKERS = [
|
| 132 |
+
Marker(f"<|reserved_{index:03d}|>", True, "reserved")
|
| 133 |
+
for index in range(64)
|
| 134 |
+
]
|
| 135 |
+
ALL_MARKERS = MARKERS + RESERVED_MARKERS
|
| 136 |
+
MARKER_TEXTS = [marker.text for marker in ALL_MARKERS]
|
| 137 |
+
|
| 138 |
+
CORE_TOKEN_IDS = {
|
| 139 |
+
"<|bos|>": 0,
|
| 140 |
+
"<|eos|>": 1,
|
| 141 |
+
"<|pad|>": 2,
|
| 142 |
+
"<|unk|>": 3,
|
| 143 |
+
"<|eod|>": 4,
|
| 144 |
+
}
|
| 145 |
+
|
| 146 |
+
ALLOWED_CHAT_ROLES = {
|
| 147 |
+
"system",
|
| 148 |
+
"developer",
|
| 149 |
+
"user",
|
| 150 |
+
"assistant",
|
| 151 |
+
"tool",
|
| 152 |
+
"function",
|
| 153 |
+
"observation",
|
| 154 |
+
}
|
| 155 |
+
|
| 156 |
+
assert len(MARKERS) == 134, f"Expected 134 requested markers, found {len(MARKERS)}"
|
| 157 |
+
assert len(ALL_MARKERS) == 198
|
| 158 |
+
assert len(MARKER_TEXTS) == len(set(MARKER_TEXTS)), "Marker strings must be unique"
|
| 159 |
+
|
source/qyrou_arch/trainer.py
ADDED
|
@@ -0,0 +1,509 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
import json
|
| 4 |
+
import math
|
| 5 |
+
import os
|
| 6 |
+
import random
|
| 7 |
+
import shutil
|
| 8 |
+
import signal
|
| 9 |
+
import time
|
| 10 |
+
from pathlib import Path
|
| 11 |
+
from statistics import median
|
| 12 |
+
from typing import Any
|
| 13 |
+
|
| 14 |
+
import numpy as np
|
| 15 |
+
import torch
|
| 16 |
+
|
| 17 |
+
from .checkpointing import CheckpointManager, directory_size
|
| 18 |
+
from .configuration_qyrou_arch import QyrouArchConfig
|
| 19 |
+
from .data import EvaluationTokens, PackedTokenStream
|
| 20 |
+
from .io_utils import load_run_config, sha256_file, sha256_json
|
| 21 |
+
from .metrics import JsonlLogger, RunningMetrics, safe_perplexity, system_telemetry
|
| 22 |
+
from .modeling_qyrou_arch import QyrouArchForCausalLM
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
class NonFiniteTrainingError(RuntimeError):
|
| 26 |
+
pass
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def token_learning_rate(
|
| 30 |
+
consumed_tokens: int,
|
| 31 |
+
total_tokens: int,
|
| 32 |
+
warmup_tokens: int,
|
| 33 |
+
peak: float,
|
| 34 |
+
minimum: float,
|
| 35 |
+
) -> float:
|
| 36 |
+
if consumed_tokens < warmup_tokens:
|
| 37 |
+
return peak * consumed_tokens / max(warmup_tokens, 1)
|
| 38 |
+
progress = (consumed_tokens - warmup_tokens) / max(total_tokens - warmup_tokens, 1)
|
| 39 |
+
progress = min(max(progress, 0.0), 1.0)
|
| 40 |
+
return minimum + 0.5 * (peak - minimum) * (1.0 + math.cos(math.pi * progress))
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
class QyrouArchTrainer:
|
| 44 |
+
def __init__(
|
| 45 |
+
self,
|
| 46 |
+
config_path: str | Path,
|
| 47 |
+
*,
|
| 48 |
+
microbatch: int,
|
| 49 |
+
grad_accum: int,
|
| 50 |
+
compile_model: bool,
|
| 51 |
+
compile_mode: str,
|
| 52 |
+
resume: str | None,
|
| 53 |
+
) -> None:
|
| 54 |
+
self.config_path = Path(config_path).resolve()
|
| 55 |
+
self.cfg = load_run_config(self.config_path)
|
| 56 |
+
self.run_cfg = self.cfg["run"]
|
| 57 |
+
self.train_cfg = self.cfg["training"]
|
| 58 |
+
self.data_cfg = self.cfg["data"]
|
| 59 |
+
self.microbatch = microbatch
|
| 60 |
+
self.grad_accum = grad_accum
|
| 61 |
+
self.compile_model = compile_model
|
| 62 |
+
self.compile_mode = compile_mode
|
| 63 |
+
self.device = torch.device(self.train_cfg["device"])
|
| 64 |
+
self.interrupt_requested = False
|
| 65 |
+
self.recoveries = 0
|
| 66 |
+
self.lr_scale = 1.0
|
| 67 |
+
self.global_step = 0
|
| 68 |
+
self.total_tokens = 0
|
| 69 |
+
self.last_checkpoint_bytes: int | None = None
|
| 70 |
+
self.qualified_throughput = False
|
| 71 |
+
self.qualified_convergence = False
|
| 72 |
+
self.baseline_validation_loss: float | None = None
|
| 73 |
+
self.qualification_tps: list[float] = []
|
| 74 |
+
self.milestones_saved: set[float] = set()
|
| 75 |
+
self.metrics = RunningMetrics()
|
| 76 |
+
self.compiler_cache_gib = 0.0
|
| 77 |
+
|
| 78 |
+
if not torch.cuda.is_available():
|
| 79 |
+
raise RuntimeError("Full training requires a CUDA GPU")
|
| 80 |
+
if not torch.cuda.is_bf16_supported():
|
| 81 |
+
raise RuntimeError("The selected CUDA GPU does not support BF16")
|
| 82 |
+
torch.manual_seed(int(self.run_cfg["seed"]))
|
| 83 |
+
torch.cuda.manual_seed_all(int(self.run_cfg["seed"]))
|
| 84 |
+
np.random.seed(int(self.run_cfg["seed"]))
|
| 85 |
+
random.seed(int(self.run_cfg["seed"]))
|
| 86 |
+
torch.set_float32_matmul_precision("high")
|
| 87 |
+
torch.backends.cuda.matmul.allow_tf32 = True
|
| 88 |
+
|
| 89 |
+
token_manifest = Path(self.run_cfg["token_cache_dir"]) / "manifest.json"
|
| 90 |
+
self.data = PackedTokenStream(
|
| 91 |
+
token_manifest,
|
| 92 |
+
int(self.data_cfg["sequence_length"]),
|
| 93 |
+
int(self.cfg["model"]["pad_token_id"]),
|
| 94 |
+
int(self.data_cfg["shuffle_seed"]),
|
| 95 |
+
shuffle_block_tokens=int(self.data_cfg["shuffle_block_tokens"]),
|
| 96 |
+
)
|
| 97 |
+
self.corpus_total_tokens = self.data.total_tokens
|
| 98 |
+
self.eval_data_path = Path(self.run_cfg["project_dir"]) / "data" / "eval" / "wikitext103-validation.bin"
|
| 99 |
+
if not self.eval_data_path.exists():
|
| 100 |
+
raise RuntimeError(f"Missing fixed validation tokens: {self.eval_data_path}")
|
| 101 |
+
self.eval_data = EvaluationTokens(
|
| 102 |
+
self.eval_data_path,
|
| 103 |
+
int(self.data_cfg["sequence_length"]),
|
| 104 |
+
int(self.cfg["model"]["pad_token_id"]),
|
| 105 |
+
)
|
| 106 |
+
checkpoint_cfg = self.cfg["checkpoints"]
|
| 107 |
+
self.checkpoints = CheckpointManager(
|
| 108 |
+
self.run_cfg["checkpoint_dir"],
|
| 109 |
+
float(checkpoint_cfg["cap_gib"]),
|
| 110 |
+
int(checkpoint_cfg["prune_count"]),
|
| 111 |
+
)
|
| 112 |
+
self.logger = JsonlLogger(Path(self.run_cfg["log_dir"]) / "training_metrics.jsonl")
|
| 113 |
+
|
| 114 |
+
resume_path = None
|
| 115 |
+
if resume == "auto":
|
| 116 |
+
resume_path = self.checkpoints.find_latest_valid()
|
| 117 |
+
elif resume:
|
| 118 |
+
resume_path = Path(resume)
|
| 119 |
+
if resume_path is not None:
|
| 120 |
+
self.raw_model = QyrouArchForCausalLM.from_pretrained(
|
| 121 |
+
resume_path / "model",
|
| 122 |
+
trust_remote_code=False,
|
| 123 |
+
)
|
| 124 |
+
else:
|
| 125 |
+
self.raw_model = QyrouArchForCausalLM(QyrouArchConfig(**self.cfg["model"]))
|
| 126 |
+
if self.raw_model.config.vocab_size != 20_000:
|
| 127 |
+
raise RuntimeError("Model vocabulary must be exactly 20,000")
|
| 128 |
+
if (
|
| 129 |
+
self.raw_model.get_input_embeddings().weight.data_ptr()
|
| 130 |
+
!= self.raw_model.get_output_embeddings().weight.data_ptr()
|
| 131 |
+
):
|
| 132 |
+
raise RuntimeError("Input and output embeddings are not tied")
|
| 133 |
+
self.raw_model.to(self.device, dtype=torch.float32)
|
| 134 |
+
self.optimizer = torch.optim.AdamW(
|
| 135 |
+
self.raw_model.parameters(),
|
| 136 |
+
lr=float(self.train_cfg["peak_learning_rate"]),
|
| 137 |
+
betas=(float(self.train_cfg["beta1"]), float(self.train_cfg["beta2"])),
|
| 138 |
+
eps=float(self.train_cfg["epsilon"]),
|
| 139 |
+
weight_decay=float(self.train_cfg["weight_decay"]),
|
| 140 |
+
fused=True,
|
| 141 |
+
)
|
| 142 |
+
if resume_path is not None:
|
| 143 |
+
self._load_checkpoint(resume_path)
|
| 144 |
+
self.train_model = (
|
| 145 |
+
torch.compile(self.raw_model, mode=self.compile_mode, fullgraph=False)
|
| 146 |
+
if compile_model
|
| 147 |
+
else self.raw_model
|
| 148 |
+
)
|
| 149 |
+
signal.signal(signal.SIGINT, self._request_interrupt)
|
| 150 |
+
signal.signal(signal.SIGTERM, self._request_interrupt)
|
| 151 |
+
|
| 152 |
+
def _request_interrupt(self, _signum: int, _frame: Any) -> None:
|
| 153 |
+
self.interrupt_requested = True
|
| 154 |
+
|
| 155 |
+
def _trainer_state(self) -> dict[str, Any]:
|
| 156 |
+
token_manifest = Path(self.run_cfg["token_cache_dir"]) / "manifest.json"
|
| 157 |
+
tokenizer_path = Path(self.run_cfg["tokenizer_dir"]) / "tokenizer.json"
|
| 158 |
+
return {
|
| 159 |
+
"version": 1,
|
| 160 |
+
"global_step": self.global_step,
|
| 161 |
+
"total_tokens": self.total_tokens,
|
| 162 |
+
"data": self.data.state_dict(),
|
| 163 |
+
"metrics": self.metrics.state_dict(),
|
| 164 |
+
"recoveries": self.recoveries,
|
| 165 |
+
"lr_scale": self.lr_scale,
|
| 166 |
+
"microbatch": self.microbatch,
|
| 167 |
+
"grad_accum": self.grad_accum,
|
| 168 |
+
"compile_model": self.compile_model,
|
| 169 |
+
"compile_mode": self.compile_mode,
|
| 170 |
+
"qualified_throughput": self.qualified_throughput,
|
| 171 |
+
"qualified_convergence": self.qualified_convergence,
|
| 172 |
+
"baseline_validation_loss": self.baseline_validation_loss,
|
| 173 |
+
"milestones_saved": sorted(self.milestones_saved),
|
| 174 |
+
"config_sha256": sha256_file(self.config_path),
|
| 175 |
+
"token_manifest_sha256": sha256_file(token_manifest),
|
| 176 |
+
"tokenizer_sha256": sha256_file(tokenizer_path),
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
def _load_checkpoint(self, path: Path) -> None:
|
| 180 |
+
state = self.checkpoints.load_training_state(path)
|
| 181 |
+
trainer = state["trainer"]
|
| 182 |
+
if trainer["config_sha256"] != sha256_file(self.config_path):
|
| 183 |
+
raise RuntimeError("Checkpoint configuration hash differs from current run")
|
| 184 |
+
if trainer["token_manifest_sha256"] != sha256_file(
|
| 185 |
+
Path(self.run_cfg["token_cache_dir"]) / "manifest.json"
|
| 186 |
+
):
|
| 187 |
+
raise RuntimeError("Checkpoint token-manifest hash differs from current cache")
|
| 188 |
+
if trainer["tokenizer_sha256"] != sha256_file(
|
| 189 |
+
Path(self.run_cfg["tokenizer_dir"]) / "tokenizer.json"
|
| 190 |
+
):
|
| 191 |
+
raise RuntimeError("Checkpoint tokenizer hash differs from current tokenizer")
|
| 192 |
+
if trainer["microbatch"] != self.microbatch or trainer["grad_accum"] != self.grad_accum:
|
| 193 |
+
raise RuntimeError("Resume batch configuration differs from checkpoint")
|
| 194 |
+
if bool(trainer.get("compile_model", False)) != self.compile_model:
|
| 195 |
+
raise RuntimeError("Resume compilation setting differs from checkpoint")
|
| 196 |
+
if trainer.get("compile_mode", "default") != self.compile_mode:
|
| 197 |
+
raise RuntimeError("Resume compilation mode differs from checkpoint")
|
| 198 |
+
self.optimizer.load_state_dict(state["optimizer"])
|
| 199 |
+
self.global_step = int(trainer["global_step"])
|
| 200 |
+
self.total_tokens = int(trainer["total_tokens"])
|
| 201 |
+
self.data.load_state_dict(trainer["data"])
|
| 202 |
+
self.metrics.load_state_dict(trainer["metrics"])
|
| 203 |
+
self.recoveries = int(trainer.get("recoveries", 0))
|
| 204 |
+
self.lr_scale = float(trainer.get("lr_scale", 1.0))
|
| 205 |
+
self.qualified_throughput = bool(trainer.get("qualified_throughput", False))
|
| 206 |
+
self.qualified_convergence = bool(trainer.get("qualified_convergence", False))
|
| 207 |
+
self.baseline_validation_loss = trainer.get("baseline_validation_loss")
|
| 208 |
+
self.milestones_saved = set(trainer.get("milestones_saved", []))
|
| 209 |
+
torch.set_rng_state(state["cpu_rng"])
|
| 210 |
+
if state.get("cuda_rng") is not None:
|
| 211 |
+
torch.cuda.set_rng_state_all(state["cuda_rng"])
|
| 212 |
+
|
| 213 |
+
def _save(self, validation_loss: float | None = None) -> Path:
|
| 214 |
+
latest = self.checkpoints.find_latest_valid()
|
| 215 |
+
if latest is not None:
|
| 216 |
+
latest_step = int(latest.name.rsplit("-", 1)[-1])
|
| 217 |
+
if latest_step == self.global_step:
|
| 218 |
+
return latest
|
| 219 |
+
path = self.checkpoints.save(
|
| 220 |
+
model=self.raw_model,
|
| 221 |
+
optimizer=self.optimizer,
|
| 222 |
+
trainer_state=self._trainer_state(),
|
| 223 |
+
step=self.global_step,
|
| 224 |
+
total_tokens=self.total_tokens,
|
| 225 |
+
validation_loss=validation_loss,
|
| 226 |
+
expected_bytes=self.last_checkpoint_bytes,
|
| 227 |
+
)
|
| 228 |
+
self.last_checkpoint_bytes = directory_size(path)
|
| 229 |
+
print(f"saved_checkpoint={path}", flush=True)
|
| 230 |
+
return path
|
| 231 |
+
|
| 232 |
+
def _recover(self, reason: str) -> None:
|
| 233 |
+
maximum = int(self.train_cfg["max_automatic_recoveries"])
|
| 234 |
+
if self.recoveries >= maximum:
|
| 235 |
+
raise RuntimeError(f"Recovery limit exceeded after: {reason}")
|
| 236 |
+
latest = self.checkpoints.find_latest_valid()
|
| 237 |
+
if latest is None:
|
| 238 |
+
raise RuntimeError(f"Non-finite training before first recovery checkpoint: {reason}")
|
| 239 |
+
recovered_model = QyrouArchForCausalLM.from_pretrained(latest / "model").to(
|
| 240 |
+
self.device,
|
| 241 |
+
dtype=torch.float32,
|
| 242 |
+
)
|
| 243 |
+
self.raw_model.load_state_dict(recovered_model.state_dict())
|
| 244 |
+
del recovered_model
|
| 245 |
+
prior_recoveries = self.recoveries
|
| 246 |
+
prior_scale = self.lr_scale
|
| 247 |
+
self._load_checkpoint(latest)
|
| 248 |
+
self.recoveries = prior_recoveries + 1
|
| 249 |
+
self.lr_scale = prior_scale * 0.5
|
| 250 |
+
self.optimizer.zero_grad(set_to_none=True)
|
| 251 |
+
self.logger.log(
|
| 252 |
+
{
|
| 253 |
+
"event": "automatic_recovery",
|
| 254 |
+
"reason": reason,
|
| 255 |
+
"checkpoint": str(latest),
|
| 256 |
+
"recoveries": self.recoveries,
|
| 257 |
+
"lr_scale": self.lr_scale,
|
| 258 |
+
}
|
| 259 |
+
)
|
| 260 |
+
|
| 261 |
+
@torch.no_grad()
|
| 262 |
+
def evaluate(self) -> float:
|
| 263 |
+
self.train_model.eval()
|
| 264 |
+
total_loss = 0.0
|
| 265 |
+
total_weight = 0
|
| 266 |
+
for input_ids, labels, tokens in self.eval_data.batches(
|
| 267 |
+
batch_size=max(1, min(self.microbatch, 4)),
|
| 268 |
+
device=self.device,
|
| 269 |
+
max_tokens=int(self.train_cfg["eval_tokens"]),
|
| 270 |
+
):
|
| 271 |
+
with torch.autocast("cuda", dtype=torch.bfloat16):
|
| 272 |
+
if self.compile_model:
|
| 273 |
+
torch.compiler.cudagraph_mark_step_begin()
|
| 274 |
+
output = self.train_model(
|
| 275 |
+
input_ids=input_ids,
|
| 276 |
+
labels=labels,
|
| 277 |
+
use_cache=False,
|
| 278 |
+
return_logits=False,
|
| 279 |
+
)
|
| 280 |
+
total_loss += float(output.loss) * tokens
|
| 281 |
+
total_weight += tokens
|
| 282 |
+
self.train_model.train()
|
| 283 |
+
return total_loss / max(total_weight, 1)
|
| 284 |
+
|
| 285 |
+
def _set_learning_rate(self) -> float:
|
| 286 |
+
lr = token_learning_rate(
|
| 287 |
+
self.total_tokens,
|
| 288 |
+
self.corpus_total_tokens,
|
| 289 |
+
int(self.train_cfg["warmup_tokens"]),
|
| 290 |
+
float(self.train_cfg["peak_learning_rate"]),
|
| 291 |
+
float(self.train_cfg["minimum_learning_rate"]),
|
| 292 |
+
) * self.lr_scale
|
| 293 |
+
for group in self.optimizer.param_groups:
|
| 294 |
+
group["lr"] = lr
|
| 295 |
+
return lr
|
| 296 |
+
|
| 297 |
+
def _check_milestones(self) -> None:
|
| 298 |
+
fraction = self.total_tokens / max(self.corpus_total_tokens, 1)
|
| 299 |
+
for target in self.cfg["checkpoints"]["milestone_fractions"]:
|
| 300 |
+
target = float(target)
|
| 301 |
+
if fraction >= target and target not in self.milestones_saved:
|
| 302 |
+
self.checkpoints.save_milestone(
|
| 303 |
+
self.raw_model,
|
| 304 |
+
target,
|
| 305 |
+
self.global_step,
|
| 306 |
+
self.total_tokens,
|
| 307 |
+
)
|
| 308 |
+
self.milestones_saved.add(target)
|
| 309 |
+
|
| 310 |
+
def train(self) -> None:
|
| 311 |
+
self.raw_model.train()
|
| 312 |
+
print(
|
| 313 |
+
f"training_start step={self.global_step} total_tokens={self.total_tokens} "
|
| 314 |
+
f"corpus_tokens={self.corpus_total_tokens} microbatch={self.microbatch} "
|
| 315 |
+
f"grad_accum={self.grad_accum} compile={self.compile_model} "
|
| 316 |
+
f"compile_mode={self.compile_mode}",
|
| 317 |
+
flush=True,
|
| 318 |
+
)
|
| 319 |
+
if self.baseline_validation_loss is None:
|
| 320 |
+
self.baseline_validation_loss = self.evaluate()
|
| 321 |
+
self.logger.log(
|
| 322 |
+
{"event": "baseline_evaluation", "validation_loss": self.baseline_validation_loss}
|
| 323 |
+
)
|
| 324 |
+
print(
|
| 325 |
+
f"baseline_validation_loss={self.baseline_validation_loss:.6f}",
|
| 326 |
+
flush=True,
|
| 327 |
+
)
|
| 328 |
+
while self.data.remaining_tokens > 0:
|
| 329 |
+
try:
|
| 330 |
+
self._train_step()
|
| 331 |
+
except NonFiniteTrainingError as exc:
|
| 332 |
+
self._recover(str(exc))
|
| 333 |
+
continue
|
| 334 |
+
if self.interrupt_requested:
|
| 335 |
+
self._save()
|
| 336 |
+
self.logger.log({"event": "controlled_interrupt", "step": self.global_step})
|
| 337 |
+
return
|
| 338 |
+
final_validation = self.evaluate()
|
| 339 |
+
self._save(final_validation)
|
| 340 |
+
self._check_milestones()
|
| 341 |
+
self._export_final(final_validation)
|
| 342 |
+
|
| 343 |
+
def _train_step(self) -> None:
|
| 344 |
+
started = time.perf_counter()
|
| 345 |
+
self.optimizer.zero_grad(set_to_none=True)
|
| 346 |
+
accumulated_tokens = 0
|
| 347 |
+
data_wait_seconds = 0.0
|
| 348 |
+
loss_values: list[torch.Tensor] = []
|
| 349 |
+
finite_loss = torch.ones((), dtype=torch.bool, device=self.device)
|
| 350 |
+
failed_range: tuple[int, int] | None = None
|
| 351 |
+
with torch.autocast("cuda", dtype=torch.bfloat16, cache_enabled=True):
|
| 352 |
+
for _ in range(self.grad_accum):
|
| 353 |
+
data_started = time.perf_counter()
|
| 354 |
+
batch = self.data.next_batch(self.microbatch, self.device)
|
| 355 |
+
data_wait_seconds += time.perf_counter() - data_started
|
| 356 |
+
if batch is None:
|
| 357 |
+
break
|
| 358 |
+
if self.compile_model:
|
| 359 |
+
torch.compiler.cudagraph_mark_step_begin()
|
| 360 |
+
output = self.train_model(
|
| 361 |
+
input_ids=batch.input_ids,
|
| 362 |
+
labels=batch.labels,
|
| 363 |
+
use_cache=False,
|
| 364 |
+
return_logits=False,
|
| 365 |
+
)
|
| 366 |
+
loss = output.loss / self.grad_accum
|
| 367 |
+
finite_loss.logical_and_(torch.isfinite(loss.detach()))
|
| 368 |
+
failed_range = (batch.start_cursor, batch.end_cursor)
|
| 369 |
+
loss.backward()
|
| 370 |
+
loss_values.append(loss.detach())
|
| 371 |
+
accumulated_tokens += batch.real_tokens
|
| 372 |
+
if accumulated_tokens == 0:
|
| 373 |
+
return
|
| 374 |
+
if not bool(finite_loss):
|
| 375 |
+
assert failed_range is not None
|
| 376 |
+
raise NonFiniteTrainingError(
|
| 377 |
+
f"non-finite loss at token range {failed_range[0]}:{failed_range[1]}"
|
| 378 |
+
)
|
| 379 |
+
grad_norm = torch.nn.utils.clip_grad_norm_(
|
| 380 |
+
self.raw_model.parameters(),
|
| 381 |
+
float(self.train_cfg["grad_clip"]),
|
| 382 |
+
)
|
| 383 |
+
if not torch.isfinite(grad_norm):
|
| 384 |
+
raise NonFiniteTrainingError(f"non-finite gradient norm at step {self.global_step + 1}")
|
| 385 |
+
learning_rate = self._set_learning_rate()
|
| 386 |
+
self.optimizer.step()
|
| 387 |
+
torch.cuda.synchronize()
|
| 388 |
+
elapsed = time.perf_counter() - started
|
| 389 |
+
self.global_step += 1
|
| 390 |
+
self.total_tokens += accumulated_tokens
|
| 391 |
+
step_loss = float(torch.stack(loss_values).sum()) * self.grad_accum / len(loss_values)
|
| 392 |
+
tps = accumulated_tokens / max(elapsed, 1e-9)
|
| 393 |
+
self.metrics.update(step_loss, tps)
|
| 394 |
+
if self.global_step > 100 and not self.qualified_throughput:
|
| 395 |
+
self.qualification_tps.append(tps)
|
| 396 |
+
if self.global_step == int(self.train_cfg["qualification_steps"]):
|
| 397 |
+
measured = median(self.qualification_tps)
|
| 398 |
+
if measured < float(self.train_cfg["minimum_tps"]):
|
| 399 |
+
self._save()
|
| 400 |
+
raise RuntimeError(
|
| 401 |
+
f"Qualification throughput {measured:,.0f} TPS is below "
|
| 402 |
+
f"{self.train_cfg['minimum_tps']:,.0f}"
|
| 403 |
+
)
|
| 404 |
+
self.qualified_throughput = True
|
| 405 |
+
if (
|
| 406 |
+
not self.qualified_convergence
|
| 407 |
+
and self.total_tokens >= int(self.train_cfg["qualification_tokens"])
|
| 408 |
+
):
|
| 409 |
+
validation = self.evaluate()
|
| 410 |
+
if validation >= float(self.baseline_validation_loss):
|
| 411 |
+
self._save(validation)
|
| 412 |
+
raise RuntimeError(
|
| 413 |
+
f"100M-token qualification did not improve validation loss: "
|
| 414 |
+
f"{self.baseline_validation_loss:.4f} -> {validation:.4f}"
|
| 415 |
+
)
|
| 416 |
+
self.qualified_convergence = True
|
| 417 |
+
self.logger.log(
|
| 418 |
+
{
|
| 419 |
+
"event": "convergence_qualified",
|
| 420 |
+
"validation_loss": validation,
|
| 421 |
+
"baseline_validation_loss": self.baseline_validation_loss,
|
| 422 |
+
}
|
| 423 |
+
)
|
| 424 |
+
if self.metrics.spike_steps >= 5000:
|
| 425 |
+
self._save()
|
| 426 |
+
raise RuntimeError("Smoothed loss rose by >10% for 5,000 consecutive steps")
|
| 427 |
+
|
| 428 |
+
validation_loss = None
|
| 429 |
+
if self.global_step % int(self.train_cfg["eval_every_steps"]) == 0:
|
| 430 |
+
validation_loss = self.evaluate()
|
| 431 |
+
if self.global_step % int(self.train_cfg["save_every_steps"]) == 0:
|
| 432 |
+
self._save(validation_loss)
|
| 433 |
+
self._check_milestones()
|
| 434 |
+
if self.global_step % int(self.train_cfg["log_every_steps"]) == 0:
|
| 435 |
+
if self.global_step == int(self.train_cfg["log_every_steps"]) or self.global_step % 1000 == 0:
|
| 436 |
+
self.compiler_cache_gib = directory_size(
|
| 437 |
+
Path(self.run_cfg["project_dir"]) / ".cache"
|
| 438 |
+
) / 2**30
|
| 439 |
+
payload = {
|
| 440 |
+
"step": self.global_step,
|
| 441 |
+
"total_tokens": self.total_tokens,
|
| 442 |
+
"corpus_progress": self.total_tokens / self.corpus_total_tokens,
|
| 443 |
+
"loss": step_loss,
|
| 444 |
+
"loss_ema_100": self.metrics.ema_100,
|
| 445 |
+
"loss_ema_1000": self.metrics.ema_1000,
|
| 446 |
+
"perplexity": safe_perplexity(step_loss),
|
| 447 |
+
"learning_rate": learning_rate,
|
| 448 |
+
"grad_norm": float(grad_norm),
|
| 449 |
+
"tokens_per_sec": tps,
|
| 450 |
+
"median_tokens_per_sec": self.metrics.median_tps,
|
| 451 |
+
"validation_loss": validation_loss,
|
| 452 |
+
"checkpoint_gib": self.checkpoints.storage_bytes() / 2**30,
|
| 453 |
+
"compiler_cache_gib": self.compiler_cache_gib,
|
| 454 |
+
"data_wait_seconds": data_wait_seconds,
|
| 455 |
+
"stream_chunk": self.data.current_shard_index,
|
| 456 |
+
"stream_block": self.data.current_block_index,
|
| 457 |
+
"data_cursor": self.data.cursor,
|
| 458 |
+
}
|
| 459 |
+
payload.update(system_telemetry())
|
| 460 |
+
self.logger.log(payload)
|
| 461 |
+
print(
|
| 462 |
+
f"step={self.global_step:07d} "
|
| 463 |
+
f"chunk={self.data.current_shard_index:03d} "
|
| 464 |
+
f"loss={step_loss:.3f} "
|
| 465 |
+
f"ppl={safe_perplexity(step_loss):.3f} "
|
| 466 |
+
f"lr={learning_rate:.2e} "
|
| 467 |
+
f"grad={float(grad_norm):.3f} "
|
| 468 |
+
f"tok/s={tps:.1f} "
|
| 469 |
+
f"total_tok={self.total_tokens} "
|
| 470 |
+
f"gpu_mem={payload.get('gpu_allocated_gib') or 0.0:.2f}GB "
|
| 471 |
+
f"gpu_peak={payload.get('gpu_peak_gib') or 0.0:.2f}GB "
|
| 472 |
+
f"gpu_reserved={payload.get('gpu_reserved_gib') or 0.0:.2f}GB "
|
| 473 |
+
f"cache={self.compiler_cache_gib:.2f}GB "
|
| 474 |
+
f"ckpt={payload['checkpoint_gib']:.2f}GB "
|
| 475 |
+
f"data_wait={data_wait_seconds:.3f}s",
|
| 476 |
+
flush=True,
|
| 477 |
+
)
|
| 478 |
+
|
| 479 |
+
def _export_final(self, validation_loss: float) -> None:
|
| 480 |
+
destination = Path(self.run_cfg["final_dir"])
|
| 481 |
+
temporary = destination.with_name(f".{destination.name}.tmp")
|
| 482 |
+
if temporary.exists():
|
| 483 |
+
shutil.rmtree(temporary)
|
| 484 |
+
temporary.mkdir(parents=True)
|
| 485 |
+
self.raw_model.save_pretrained(temporary, safe_serialization=True)
|
| 486 |
+
shutil.copytree(
|
| 487 |
+
self.run_cfg["tokenizer_dir"],
|
| 488 |
+
temporary,
|
| 489 |
+
dirs_exist_ok=True,
|
| 490 |
+
)
|
| 491 |
+
(temporary / "training_summary.json").write_text(
|
| 492 |
+
json.dumps(
|
| 493 |
+
{
|
| 494 |
+
"global_step": self.global_step,
|
| 495 |
+
"total_tokens": self.total_tokens,
|
| 496 |
+
"validation_loss": validation_loss,
|
| 497 |
+
"validation_perplexity": safe_perplexity(validation_loss),
|
| 498 |
+
"median_tokens_per_sec": self.metrics.median_tps,
|
| 499 |
+
"qualified_throughput": self.qualified_throughput,
|
| 500 |
+
"qualified_convergence": self.qualified_convergence,
|
| 501 |
+
},
|
| 502 |
+
indent=2,
|
| 503 |
+
)
|
| 504 |
+
+ "\n",
|
| 505 |
+
encoding="utf-8",
|
| 506 |
+
)
|
| 507 |
+
if destination.exists():
|
| 508 |
+
raise RuntimeError(f"Final model directory already exists: {destination}")
|
| 509 |
+
os.replace(temporary, destination)
|
source/qyrou_arch/triton_kernels.py
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
import torch
|
| 4 |
+
import triton
|
| 5 |
+
import triton.language as tl
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
def _settings(n_cols: int) -> tuple[int, int]:
|
| 9 |
+
block_size = triton.next_power_of_2(n_cols)
|
| 10 |
+
if block_size > 65_536:
|
| 11 |
+
raise ValueError(f"Unsupported SwiGLU width: {n_cols}")
|
| 12 |
+
num_warps = 4 if block_size < 2_048 else 8
|
| 13 |
+
return block_size, num_warps
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
@triton.jit
|
| 17 |
+
def _packed_swiglu_forward_kernel(
|
| 18 |
+
packed_ptr,
|
| 19 |
+
output_ptr,
|
| 20 |
+
packed_stride: tl.constexpr,
|
| 21 |
+
output_stride: tl.constexpr,
|
| 22 |
+
n_cols: tl.constexpr,
|
| 23 |
+
block_size: tl.constexpr,
|
| 24 |
+
):
|
| 25 |
+
row = tl.program_id(0).to(tl.int64)
|
| 26 |
+
offsets = tl.arange(0, block_size)
|
| 27 |
+
mask = offsets < n_cols
|
| 28 |
+
packed_row = packed_ptr + row * packed_stride
|
| 29 |
+
gate = tl.load(packed_row + offsets, mask=mask, other=0.0).to(tl.float32)
|
| 30 |
+
up = tl.load(packed_row + n_cols + offsets, mask=mask, other=0.0)
|
| 31 |
+
activated = (gate * tl.sigmoid(gate)).cast(up.dtype) * up
|
| 32 |
+
tl.store(output_ptr + row * output_stride + offsets, activated, mask=mask)
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
@triton.jit
|
| 36 |
+
def _packed_swiglu_backward_kernel(
|
| 37 |
+
grad_output_ptr,
|
| 38 |
+
packed_ptr,
|
| 39 |
+
grad_packed_ptr,
|
| 40 |
+
grad_output_stride: tl.constexpr,
|
| 41 |
+
packed_stride: tl.constexpr,
|
| 42 |
+
n_cols: tl.constexpr,
|
| 43 |
+
block_size: tl.constexpr,
|
| 44 |
+
):
|
| 45 |
+
row = tl.program_id(0).to(tl.int64)
|
| 46 |
+
offsets = tl.arange(0, block_size)
|
| 47 |
+
mask = offsets < n_cols
|
| 48 |
+
packed_row = packed_ptr + row * packed_stride
|
| 49 |
+
grad_packed_row = grad_packed_ptr + row * packed_stride
|
| 50 |
+
grad_output = tl.load(
|
| 51 |
+
grad_output_ptr + row * grad_output_stride + offsets,
|
| 52 |
+
mask=mask,
|
| 53 |
+
other=0.0,
|
| 54 |
+
)
|
| 55 |
+
gate = tl.load(packed_row + offsets, mask=mask, other=0.0).to(tl.float32)
|
| 56 |
+
up = tl.load(packed_row + n_cols + offsets, mask=mask, other=0.0)
|
| 57 |
+
sigmoid_gate = tl.sigmoid(gate)
|
| 58 |
+
silu_gate = gate * sigmoid_gate
|
| 59 |
+
grad_up = grad_output * silu_gate
|
| 60 |
+
grad_gate = grad_output * up * (sigmoid_gate + silu_gate * (1.0 - sigmoid_gate))
|
| 61 |
+
tl.store(grad_packed_row + offsets, grad_gate, mask=mask)
|
| 62 |
+
tl.store(grad_packed_row + n_cols + offsets, grad_up, mask=mask)
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
class PackedSwiGLUFunction(torch.autograd.Function):
|
| 66 |
+
@staticmethod
|
| 67 |
+
def forward(ctx, packed: torch.Tensor) -> torch.Tensor:
|
| 68 |
+
if not packed.is_cuda:
|
| 69 |
+
raise ValueError("PackedSwiGLUFunction requires a CUDA tensor")
|
| 70 |
+
if packed.dtype not in (torch.float16, torch.bfloat16, torch.float32):
|
| 71 |
+
raise TypeError(f"Unsupported PackedSwiGLU dtype: {packed.dtype}")
|
| 72 |
+
if packed.shape[-1] % 2:
|
| 73 |
+
raise ValueError("Packed gate/up dimension must be even")
|
| 74 |
+
packed = packed.contiguous()
|
| 75 |
+
n_cols = packed.shape[-1] // 2
|
| 76 |
+
packed_2d = packed.view(-1, 2 * n_cols)
|
| 77 |
+
output = torch.empty((packed_2d.shape[0], n_cols), dtype=packed.dtype, device=packed.device)
|
| 78 |
+
block_size, num_warps = _settings(n_cols)
|
| 79 |
+
_packed_swiglu_forward_kernel[(packed_2d.shape[0],)](
|
| 80 |
+
packed_2d,
|
| 81 |
+
output,
|
| 82 |
+
packed_2d.stride(0),
|
| 83 |
+
output.stride(0),
|
| 84 |
+
n_cols=n_cols,
|
| 85 |
+
block_size=block_size,
|
| 86 |
+
num_warps=num_warps,
|
| 87 |
+
)
|
| 88 |
+
ctx.save_for_backward(packed_2d)
|
| 89 |
+
ctx.original_shape = packed.shape
|
| 90 |
+
ctx.n_cols = n_cols
|
| 91 |
+
ctx.block_size = block_size
|
| 92 |
+
ctx.num_warps = num_warps
|
| 93 |
+
return output.view(*packed.shape[:-1], n_cols)
|
| 94 |
+
|
| 95 |
+
@staticmethod
|
| 96 |
+
def backward(ctx, grad_output: torch.Tensor) -> tuple[torch.Tensor]:
|
| 97 |
+
(packed_2d,) = ctx.saved_tensors
|
| 98 |
+
grad_output_2d = grad_output.contiguous().view(-1, ctx.n_cols)
|
| 99 |
+
grad_packed = torch.empty_like(packed_2d)
|
| 100 |
+
_packed_swiglu_backward_kernel[(packed_2d.shape[0],)](
|
| 101 |
+
grad_output_2d,
|
| 102 |
+
packed_2d,
|
| 103 |
+
grad_packed,
|
| 104 |
+
grad_output_2d.stride(0),
|
| 105 |
+
packed_2d.stride(0),
|
| 106 |
+
n_cols=ctx.n_cols,
|
| 107 |
+
block_size=ctx.block_size,
|
| 108 |
+
num_warps=ctx.num_warps,
|
| 109 |
+
)
|
| 110 |
+
return (grad_packed.view(ctx.original_shape),)
|
source/requirements-windows.lock
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
datasets>=4,<5
|
| 2 |
+
transformers==5.13.0
|
| 3 |
+
tokenizers==0.22.2
|
| 4 |
+
safetensors>=0.8,<0.9
|
| 5 |
+
numpy==2.4.6
|
| 6 |
+
psutil>=6.1,<7
|
| 7 |
+
pytest>=8.3,<9
|
source/scripts/audit_shuffled_stream.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
import argparse
|
| 4 |
+
import io
|
| 5 |
+
import json
|
| 6 |
+
|
| 7 |
+
import numpy as np
|
| 8 |
+
import torch
|
| 9 |
+
|
| 10 |
+
from qyrou_arch.data import PackedTokenStream
|
| 11 |
+
from qyrou_arch.io_utils import load_run_config
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def main() -> None:
|
| 15 |
+
parser = argparse.ArgumentParser()
|
| 16 |
+
parser.add_argument("--config", default="configs/qyrou_1_exp_base.json")
|
| 17 |
+
args = parser.parse_args()
|
| 18 |
+
|
| 19 |
+
cfg = load_run_config(args.config)
|
| 20 |
+
data_cfg = cfg["data"]
|
| 21 |
+
run_cfg = cfg["run"]
|
| 22 |
+
stream = PackedTokenStream(
|
| 23 |
+
f"{run_cfg['token_cache_dir']}\\manifest.json",
|
| 24 |
+
sequence_length=int(data_cfg["sequence_length"]),
|
| 25 |
+
pad_token_id=int(cfg["model"]["pad_token_id"]),
|
| 26 |
+
seed=int(data_cfg["shuffle_seed"]),
|
| 27 |
+
shuffle_block_tokens=int(data_cfg["shuffle_block_tokens"]),
|
| 28 |
+
)
|
| 29 |
+
|
| 30 |
+
unique = np.unique(stream.permutation)
|
| 31 |
+
if len(unique) != len(stream.permutation):
|
| 32 |
+
raise RuntimeError("Shuffled stream contains a repeated block")
|
| 33 |
+
if len(unique) and (int(unique[0]) != 0 or int(unique[-1]) != len(unique) - 1):
|
| 34 |
+
raise RuntimeError("Shuffled stream omits at least one block")
|
| 35 |
+
block_token_sum = sum(length for _, _, length in stream.blocks)
|
| 36 |
+
manifest_tokens = int(stream.manifest["total_tokens"])
|
| 37 |
+
if block_token_sum != manifest_tokens or stream.total_tokens != manifest_tokens:
|
| 38 |
+
raise RuntimeError("Shuffled block lengths do not match the token manifest")
|
| 39 |
+
|
| 40 |
+
state = stream.state_dict()
|
| 41 |
+
serialized = io.BytesIO()
|
| 42 |
+
torch.save(state, serialized)
|
| 43 |
+
serialized.seek(0)
|
| 44 |
+
restored_state = torch.load(serialized, map_location="cpu", weights_only=False)
|
| 45 |
+
|
| 46 |
+
sequence_length = int(data_cfg["sequence_length"])
|
| 47 |
+
boundary_cursor = max(0, stream.prefix[1] - sequence_length)
|
| 48 |
+
stream.seek(boundary_cursor)
|
| 49 |
+
restored_state["cursor"] = boundary_cursor
|
| 50 |
+
expected = stream.read_tokens(sequence_length * 4)
|
| 51 |
+
|
| 52 |
+
resumed = PackedTokenStream(
|
| 53 |
+
f"{run_cfg['token_cache_dir']}\\manifest.json",
|
| 54 |
+
sequence_length=sequence_length,
|
| 55 |
+
pad_token_id=int(cfg["model"]["pad_token_id"]),
|
| 56 |
+
seed=int(data_cfg["shuffle_seed"]),
|
| 57 |
+
shuffle_block_tokens=int(data_cfg["shuffle_block_tokens"]),
|
| 58 |
+
)
|
| 59 |
+
resumed.load_state_dict(restored_state)
|
| 60 |
+
replay = resumed.read_tokens(sequence_length * 4)
|
| 61 |
+
if not np.array_equal(expected, replay):
|
| 62 |
+
raise RuntimeError("Shuffled stream did not resume with the exact next tokens")
|
| 63 |
+
|
| 64 |
+
print(
|
| 65 |
+
json.dumps(
|
| 66 |
+
{
|
| 67 |
+
"status": "passed",
|
| 68 |
+
"total_tokens": stream.total_tokens,
|
| 69 |
+
"unique_blocks": len(stream.blocks),
|
| 70 |
+
"shuffle_block_tokens": stream.shuffle_block_tokens,
|
| 71 |
+
"permutation_sha256": stream.permutation_sha256,
|
| 72 |
+
"resume_across_block_boundary": "exact",
|
| 73 |
+
},
|
| 74 |
+
indent=2,
|
| 75 |
+
)
|
| 76 |
+
)
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
if __name__ == "__main__":
|
| 80 |
+
main()
|
source/scripts/autotune.py
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
import argparse
|
| 4 |
+
import gc
|
| 5 |
+
import json
|
| 6 |
+
import logging
|
| 7 |
+
import time
|
| 8 |
+
import warnings
|
| 9 |
+
from pathlib import Path
|
| 10 |
+
from statistics import mean, median
|
| 11 |
+
|
| 12 |
+
import torch
|
| 13 |
+
|
| 14 |
+
from qyrou_arch.configuration_qyrou_arch import QyrouArchConfig
|
| 15 |
+
from qyrou_arch.io_utils import atomic_write_json, load_run_config
|
| 16 |
+
from qyrou_arch.modeling_qyrou_arch import QyrouArchForCausalLM
|
| 17 |
+
|
| 18 |
+
warnings.filterwarnings(
|
| 19 |
+
"ignore",
|
| 20 |
+
message=r"Dynamo does not know how to trace the builtin .*native_specialize_impl.*",
|
| 21 |
+
)
|
| 22 |
+
logging.getLogger("torch._inductor.utils").setLevel(logging.ERROR)
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def benchmark_candidate(
|
| 26 |
+
model_cfg: dict,
|
| 27 |
+
microbatch: int,
|
| 28 |
+
grad_accum: int,
|
| 29 |
+
compile_model: bool,
|
| 30 |
+
compile_mode: str,
|
| 31 |
+
steps: int,
|
| 32 |
+
warmup: int,
|
| 33 |
+
) -> dict[str, object]:
|
| 34 |
+
torch.cuda.empty_cache()
|
| 35 |
+
torch.cuda.reset_peak_memory_stats()
|
| 36 |
+
model = QyrouArchForCausalLM(QyrouArchConfig(**model_cfg)).cuda().float().train()
|
| 37 |
+
optimizer = torch.optim.AdamW(model.parameters(), lr=6e-4, fused=True)
|
| 38 |
+
runner = torch.compile(model, mode=compile_mode, fullgraph=False) if compile_model else model
|
| 39 |
+
sequence_length = int(model_cfg["max_position_embeddings"])
|
| 40 |
+
input_ids = torch.randint(
|
| 41 |
+
0,
|
| 42 |
+
int(model_cfg["vocab_size"]),
|
| 43 |
+
(microbatch, sequence_length),
|
| 44 |
+
device="cuda",
|
| 45 |
+
)
|
| 46 |
+
timings: list[float] = []
|
| 47 |
+
for step in range(warmup + steps):
|
| 48 |
+
started = time.perf_counter()
|
| 49 |
+
optimizer.zero_grad(set_to_none=True)
|
| 50 |
+
with torch.autocast("cuda", dtype=torch.bfloat16, cache_enabled=True):
|
| 51 |
+
for _ in range(grad_accum):
|
| 52 |
+
if compile_model:
|
| 53 |
+
torch.compiler.cudagraph_mark_step_begin()
|
| 54 |
+
loss = runner(
|
| 55 |
+
input_ids=input_ids,
|
| 56 |
+
labels=input_ids,
|
| 57 |
+
use_cache=False,
|
| 58 |
+
return_logits=False,
|
| 59 |
+
).loss / grad_accum
|
| 60 |
+
loss.backward()
|
| 61 |
+
torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)
|
| 62 |
+
optimizer.step()
|
| 63 |
+
torch.cuda.synchronize()
|
| 64 |
+
if step >= warmup:
|
| 65 |
+
timings.append(time.perf_counter() - started)
|
| 66 |
+
tokens_per_step = microbatch * sequence_length * grad_accum
|
| 67 |
+
throughputs = sorted(tokens_per_step / elapsed for elapsed in timings)
|
| 68 |
+
|
| 69 |
+
def percentile(fraction: float) -> float:
|
| 70 |
+
return throughputs[round((len(throughputs) - 1) * fraction)]
|
| 71 |
+
|
| 72 |
+
result = {
|
| 73 |
+
"microbatch": microbatch,
|
| 74 |
+
"grad_accum": grad_accum,
|
| 75 |
+
"compile": compile_model,
|
| 76 |
+
"compile_mode": compile_mode if compile_model else None,
|
| 77 |
+
"tokens_per_sec": median(throughputs),
|
| 78 |
+
"average_tokens_per_sec": mean(throughputs),
|
| 79 |
+
"p10_tokens_per_sec": percentile(0.10),
|
| 80 |
+
"p90_tokens_per_sec": percentile(0.90),
|
| 81 |
+
"average_step_seconds": mean(timings),
|
| 82 |
+
"measured_steps": len(timings),
|
| 83 |
+
"peak_gib": torch.cuda.max_memory_allocated() / 2**30,
|
| 84 |
+
}
|
| 85 |
+
del runner, optimizer, model, input_ids
|
| 86 |
+
if compile_model:
|
| 87 |
+
torch.compiler.reset()
|
| 88 |
+
gc.collect()
|
| 89 |
+
torch.cuda.empty_cache()
|
| 90 |
+
return result
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
def main() -> None:
|
| 94 |
+
parser = argparse.ArgumentParser()
|
| 95 |
+
parser.add_argument("--config", default="configs/qyrou_1_exp_base.json")
|
| 96 |
+
parser.add_argument("--steps", type=int, default=50)
|
| 97 |
+
parser.add_argument("--warmup", type=int, default=10)
|
| 98 |
+
parser.add_argument(
|
| 99 |
+
"--candidate",
|
| 100 |
+
nargs=2,
|
| 101 |
+
type=int,
|
| 102 |
+
metavar=("MICROBATCH", "GRAD_ACCUM"),
|
| 103 |
+
help="Benchmark only one candidate; useful for an isolated confirmation run.",
|
| 104 |
+
)
|
| 105 |
+
parser.add_argument("--eager-only", action="store_true")
|
| 106 |
+
parser.add_argument("--compiled-only", action="store_true")
|
| 107 |
+
parser.add_argument(
|
| 108 |
+
"--compile-mode",
|
| 109 |
+
choices=("default", "reduce-overhead", "max-autotune-no-cudagraphs"),
|
| 110 |
+
default="default",
|
| 111 |
+
)
|
| 112 |
+
parser.add_argument(
|
| 113 |
+
"--attention-backend",
|
| 114 |
+
choices=("cudnn", "auto", "flash"),
|
| 115 |
+
help="Override the configured SDPA backend for an isolated benchmark.",
|
| 116 |
+
)
|
| 117 |
+
args = parser.parse_args()
|
| 118 |
+
if args.eager_only and args.compiled_only:
|
| 119 |
+
parser.error("--eager-only and --compiled-only are mutually exclusive")
|
| 120 |
+
cfg = load_run_config(args.config)
|
| 121 |
+
torch.set_float32_matmul_precision("high")
|
| 122 |
+
torch.backends.cuda.matmul.allow_tf32 = True
|
| 123 |
+
model_cfg = dict(cfg["model"])
|
| 124 |
+
if args.attention_backend:
|
| 125 |
+
model_cfg["attention_backend"] = args.attention_backend
|
| 126 |
+
results = []
|
| 127 |
+
candidates = [args.candidate] if args.candidate else cfg["training"]["autotune_candidates"]
|
| 128 |
+
compile_modes = (False,) if args.eager_only else ((True,) if args.compiled_only else (False, True))
|
| 129 |
+
for microbatch, grad_accum in candidates:
|
| 130 |
+
for compile_model in compile_modes:
|
| 131 |
+
try:
|
| 132 |
+
result = benchmark_candidate(
|
| 133 |
+
model_cfg,
|
| 134 |
+
int(microbatch),
|
| 135 |
+
int(grad_accum),
|
| 136 |
+
compile_model,
|
| 137 |
+
args.compile_mode,
|
| 138 |
+
args.steps,
|
| 139 |
+
args.warmup,
|
| 140 |
+
)
|
| 141 |
+
result["attention_backend"] = model_cfg["attention_backend"]
|
| 142 |
+
except (torch.cuda.OutOfMemoryError, RuntimeError) as exc:
|
| 143 |
+
result = {
|
| 144 |
+
"microbatch": microbatch,
|
| 145 |
+
"grad_accum": grad_accum,
|
| 146 |
+
"compile": compile_model,
|
| 147 |
+
"error": str(exc),
|
| 148 |
+
}
|
| 149 |
+
print(json.dumps(result), flush=True)
|
| 150 |
+
results.append(result)
|
| 151 |
+
valid = [result for result in results if "tokens_per_sec" in result]
|
| 152 |
+
if not valid:
|
| 153 |
+
raise RuntimeError("No autotune candidate completed")
|
| 154 |
+
eager_results = [result for result in valid if not result["compile"]]
|
| 155 |
+
best_eager = (
|
| 156 |
+
max(eager_results, key=lambda result: result["tokens_per_sec"])
|
| 157 |
+
if eager_results
|
| 158 |
+
else None
|
| 159 |
+
)
|
| 160 |
+
best = max(valid, key=lambda result: result["tokens_per_sec"])
|
| 161 |
+
minimum_gain = float(cfg["training"]["compile_minimum_improvement"])
|
| 162 |
+
if (
|
| 163 |
+
best["compile"]
|
| 164 |
+
and best_eager is not None
|
| 165 |
+
and best["tokens_per_sec"] < best_eager["tokens_per_sec"] * (1 + minimum_gain)
|
| 166 |
+
):
|
| 167 |
+
best = best_eager
|
| 168 |
+
artifact = {
|
| 169 |
+
"selected": best,
|
| 170 |
+
"best_eager": best_eager,
|
| 171 |
+
"results": results,
|
| 172 |
+
"minimum_compile_gain": minimum_gain,
|
| 173 |
+
}
|
| 174 |
+
destination = Path(cfg["run"]["project_dir"]) / "artifacts" / "autotune.json"
|
| 175 |
+
atomic_write_json(destination, artifact)
|
| 176 |
+
print(json.dumps(artifact["selected"], indent=2))
|
| 177 |
+
|
| 178 |
+
|
| 179 |
+
if __name__ == "__main__":
|
| 180 |
+
main()
|
source/scripts/bootstrap_windows.ps1
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[CmdletBinding()]
|
| 2 |
+
param()
|
| 3 |
+
|
| 4 |
+
$ErrorActionPreference = "Stop"
|
| 5 |
+
$Project = Split-Path -Parent $PSScriptRoot
|
| 6 |
+
Set-Location $Project
|
| 7 |
+
$env:UV_CACHE_DIR = Join-Path $Project ".cache\uv"
|
| 8 |
+
$env:UV_PYTHON_INSTALL_DIR = Join-Path $Project ".tools\python"
|
| 9 |
+
|
| 10 |
+
function Assert-LastExitCode([string]$Action) {
|
| 11 |
+
if ($LASTEXITCODE -ne 0) {
|
| 12 |
+
throw "$Action failed with exit code $LASTEXITCODE"
|
| 13 |
+
}
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
$UvCommand = Get-Command uv -ErrorAction SilentlyContinue
|
| 17 |
+
if ($UvCommand) {
|
| 18 |
+
$Uv = $UvCommand.Source
|
| 19 |
+
} else {
|
| 20 |
+
$UvDirectory = Join-Path $Project ".tools\uv"
|
| 21 |
+
$Uv = Join-Path $UvDirectory "uv.exe"
|
| 22 |
+
if (-not (Test-Path $Uv)) {
|
| 23 |
+
$Installer = Join-Path $Project ".cache\uv-installer.ps1"
|
| 24 |
+
New-Item -ItemType Directory -Force (Split-Path $Installer) | Out-Null
|
| 25 |
+
$env:UV_UNMANAGED_INSTALL = $UvDirectory
|
| 26 |
+
$env:UV_NO_MODIFY_PATH = "1"
|
| 27 |
+
Invoke-WebRequest "https://astral.sh/uv/0.11.32/install.ps1" -OutFile $Installer
|
| 28 |
+
& powershell.exe -NoProfile -ExecutionPolicy Bypass -File $Installer
|
| 29 |
+
}
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
& $Uv python install 3.12
|
| 33 |
+
Assert-LastExitCode "Python 3.12 installation"
|
| 34 |
+
$NeedsVenv = -not (Test-Path ".venv\Scripts\python.exe")
|
| 35 |
+
if (-not $NeedsVenv) {
|
| 36 |
+
$PriorErrorPreference = $ErrorActionPreference
|
| 37 |
+
$ErrorActionPreference = "SilentlyContinue"
|
| 38 |
+
& ".venv\Scripts\python.exe" -c "import torch" 2>$null
|
| 39 |
+
$NeedsVenv = $LASTEXITCODE -ne 0
|
| 40 |
+
$ErrorActionPreference = $PriorErrorPreference
|
| 41 |
+
}
|
| 42 |
+
if ($NeedsVenv) {
|
| 43 |
+
& $Uv venv --clear --python 3.12 .venv
|
| 44 |
+
Assert-LastExitCode "Virtual environment creation"
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
& $Uv pip install --python ".venv\Scripts\python.exe" --index-url "https://download.pytorch.org/whl/cu130" "torch==2.12.0+cu130"
|
| 48 |
+
Assert-LastExitCode "CUDA PyTorch installation"
|
| 49 |
+
& $Uv pip install --python ".venv\Scripts\python.exe" -r requirements-windows.lock
|
| 50 |
+
Assert-LastExitCode "Locked dependency installation"
|
| 51 |
+
& $Uv pip install --python ".venv\Scripts\python.exe" "triton-windows==3.7.1.post27"
|
| 52 |
+
Assert-LastExitCode "Triton-Windows installation"
|
| 53 |
+
& $Uv pip install --python ".venv\Scripts\python.exe" --no-deps "liger-kernel==0.8.0" "cut-cross-entropy==25.1.1"
|
| 54 |
+
Assert-LastExitCode "Liger and cut-cross-entropy installation"
|
| 55 |
+
& $Uv pip install --python ".venv\Scripts\python.exe" -e .
|
| 56 |
+
Assert-LastExitCode "Editable project installation"
|
| 57 |
+
# `liger-kernel` declares the Linux distribution name `triton`; on Windows the
|
| 58 |
+
# compatible provider is `triton-windows`, so generic `pip check` reports a
|
| 59 |
+
# false missing-distribution error. The import/runtime smoke below is authoritative.
|
| 60 |
+
|
| 61 |
+
$env:TORCHINDUCTOR_CACHE_DIR = Join-Path $Project ".cache\torchinductor"
|
| 62 |
+
$env:TRITON_CACHE_DIR = Join-Path $Project ".cache\triton"
|
| 63 |
+
New-Item -ItemType Directory -Force $env:TORCHINDUCTOR_CACHE_DIR | Out-Null
|
| 64 |
+
New-Item -ItemType Directory -Force $env:TRITON_CACHE_DIR | Out-Null
|
| 65 |
+
|
| 66 |
+
& ".venv\Scripts\python.exe" -c "import torch, transformers, triton; print(torch.__version__, torch.version.cuda, transformers.__version__, triton.__version__)"
|
| 67 |
+
Assert-LastExitCode "Runtime import smoke test"
|
| 68 |
+
Write-Host "Qyrou-1 training environment is ready."
|
source/scripts/fetch_preview_assets.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
import argparse
|
| 4 |
+
import os
|
| 5 |
+
import urllib.request
|
| 6 |
+
from pathlib import Path
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
FILES = [
|
| 10 |
+
"README.md",
|
| 11 |
+
"config.json",
|
| 12 |
+
"generation_config.json",
|
| 13 |
+
"modeling_qyrou_arch.py",
|
| 14 |
+
"triton_kernels.py",
|
| 15 |
+
"stats/run_config.yaml",
|
| 16 |
+
"stats/training_state.json",
|
| 17 |
+
]
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
def main() -> None:
|
| 21 |
+
parser = argparse.ArgumentParser()
|
| 22 |
+
parser.add_argument("--repo", default="QyrouArchLabs/QyrouArch-65M-Preview")
|
| 23 |
+
parser.add_argument("--revision", default="94f25e19b0efb71b4534fe890afb58f5a8e8a4e1")
|
| 24 |
+
parser.add_argument("--output", default="artifacts/preview_reference")
|
| 25 |
+
args = parser.parse_args()
|
| 26 |
+
token = os.environ.get("HF_TOKEN")
|
| 27 |
+
if not token:
|
| 28 |
+
raise RuntimeError("Set HF_TOKEN for this process; the script never persists it")
|
| 29 |
+
output = Path(args.output).resolve()
|
| 30 |
+
output.mkdir(parents=True, exist_ok=True)
|
| 31 |
+
for filename in FILES:
|
| 32 |
+
request = urllib.request.Request(
|
| 33 |
+
f"https://huggingface.co/{args.repo}/resolve/{args.revision}/{filename}",
|
| 34 |
+
headers={"Authorization": f"Bearer {token}"},
|
| 35 |
+
)
|
| 36 |
+
with urllib.request.urlopen(request, timeout=60) as response:
|
| 37 |
+
content = response.read()
|
| 38 |
+
destination = output / filename
|
| 39 |
+
destination.parent.mkdir(parents=True, exist_ok=True)
|
| 40 |
+
temporary = destination.with_suffix(destination.suffix + ".tmp")
|
| 41 |
+
temporary.write_bytes(content)
|
| 42 |
+
os.replace(temporary, destination)
|
| 43 |
+
print(destination)
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
if __name__ == "__main__":
|
| 47 |
+
main()
|
| 48 |
+
|
source/scripts/generate.py
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
import argparse
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
|
| 6 |
+
import torch
|
| 7 |
+
from transformers import PreTrainedTokenizerFast
|
| 8 |
+
|
| 9 |
+
from qyrou_arch.cache import QyrouArchHybridCache
|
| 10 |
+
from qyrou_arch.modeling_qyrou_arch import QyrouArchForCausalLM
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
def main() -> None:
|
| 14 |
+
parser = argparse.ArgumentParser()
|
| 15 |
+
parser.add_argument("model")
|
| 16 |
+
parser.add_argument("prompt")
|
| 17 |
+
parser.add_argument("--max-new-tokens", type=int, default=128)
|
| 18 |
+
parser.add_argument("--static-cache", action="store_true")
|
| 19 |
+
args = parser.parse_args()
|
| 20 |
+
model_path = Path(args.model)
|
| 21 |
+
tokenizer = PreTrainedTokenizerFast.from_pretrained(model_path)
|
| 22 |
+
model = QyrouArchForCausalLM.from_pretrained(model_path).cuda().to(torch.bfloat16).eval()
|
| 23 |
+
inputs = tokenizer(args.prompt, return_tensors="pt").to("cuda")
|
| 24 |
+
cache = (
|
| 25 |
+
QyrouArchHybridCache(model.config.num_hidden_layers, model.config.max_position_embeddings)
|
| 26 |
+
if args.static_cache
|
| 27 |
+
else QyrouArchHybridCache(model.config.num_hidden_layers)
|
| 28 |
+
)
|
| 29 |
+
with torch.inference_mode():
|
| 30 |
+
output = model.generate(
|
| 31 |
+
**inputs,
|
| 32 |
+
past_key_values=cache,
|
| 33 |
+
max_new_tokens=args.max_new_tokens,
|
| 34 |
+
do_sample=True,
|
| 35 |
+
temperature=0.8,
|
| 36 |
+
top_p=0.95,
|
| 37 |
+
use_cache=True,
|
| 38 |
+
pad_token_id=tokenizer.pad_token_id,
|
| 39 |
+
eos_token_id=tokenizer.eos_token_id,
|
| 40 |
+
)
|
| 41 |
+
print(tokenizer.decode(output[0], skip_special_tokens=False))
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
if __name__ == "__main__":
|
| 45 |
+
main()
|
| 46 |
+
|
source/scripts/gpu_smoke.py
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
import argparse
|
| 4 |
+
import json
|
| 5 |
+
|
| 6 |
+
import torch
|
| 7 |
+
|
| 8 |
+
from qyrou_arch.cache import QyrouArchHybridCache
|
| 9 |
+
from qyrou_arch.configuration_qyrou_arch import QyrouArchConfig
|
| 10 |
+
from qyrou_arch.io_utils import load_run_config
|
| 11 |
+
from qyrou_arch.modeling_qyrou_arch import QyrouArchForCausalLM
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def main() -> None:
|
| 15 |
+
parser = argparse.ArgumentParser()
|
| 16 |
+
parser.add_argument("--config", default="configs/qyrou_1_exp_base.json")
|
| 17 |
+
parser.add_argument("--sequence-length", type=int, default=128)
|
| 18 |
+
args = parser.parse_args()
|
| 19 |
+
cfg = load_run_config(args.config)
|
| 20 |
+
if not torch.cuda.is_available() or not torch.cuda.is_bf16_supported():
|
| 21 |
+
raise RuntimeError("GPU smoke requires BF16 CUDA")
|
| 22 |
+
torch.manual_seed(int(cfg["run"]["seed"]))
|
| 23 |
+
torch.cuda.manual_seed_all(int(cfg["run"]["seed"]))
|
| 24 |
+
torch.cuda.reset_peak_memory_stats()
|
| 25 |
+
model = QyrouArchForCausalLM(QyrouArchConfig(**cfg["model"])).cuda().float().train()
|
| 26 |
+
optimizer = torch.optim.AdamW(model.parameters(), lr=6e-4, fused=True)
|
| 27 |
+
tokens = torch.randint(
|
| 28 |
+
5,
|
| 29 |
+
model.config.vocab_size,
|
| 30 |
+
(1, args.sequence_length),
|
| 31 |
+
device="cuda",
|
| 32 |
+
)
|
| 33 |
+
with torch.autocast("cuda", dtype=torch.bfloat16):
|
| 34 |
+
output = model(
|
| 35 |
+
input_ids=tokens,
|
| 36 |
+
labels=tokens,
|
| 37 |
+
use_cache=False,
|
| 38 |
+
return_logits=False,
|
| 39 |
+
)
|
| 40 |
+
if not torch.isfinite(output.loss):
|
| 41 |
+
raise RuntimeError(f"Non-finite smoke loss: {output.loss}")
|
| 42 |
+
output.loss.backward()
|
| 43 |
+
grad_norm = torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)
|
| 44 |
+
if not torch.isfinite(grad_norm):
|
| 45 |
+
raise RuntimeError(f"Non-finite smoke gradient norm: {grad_norm}")
|
| 46 |
+
optimizer.step()
|
| 47 |
+
optimizer.zero_grad(set_to_none=True)
|
| 48 |
+
|
| 49 |
+
model.eval()
|
| 50 |
+
cache_tokens = tokens[:, :16]
|
| 51 |
+
with torch.inference_mode(), torch.autocast("cuda", dtype=torch.bfloat16):
|
| 52 |
+
full = model(cache_tokens, use_cache=False).logits
|
| 53 |
+
cache = QyrouArchHybridCache(model.config.num_hidden_layers)
|
| 54 |
+
first = model(cache_tokens[:, :10], past_key_values=cache, use_cache=True).logits
|
| 55 |
+
second = model(
|
| 56 |
+
cache_tokens[:, 10:],
|
| 57 |
+
past_key_values=cache,
|
| 58 |
+
cache_position=torch.arange(10, 16, device="cuda"),
|
| 59 |
+
use_cache=True,
|
| 60 |
+
).logits
|
| 61 |
+
cached = torch.cat((first, second), dim=1)
|
| 62 |
+
torch.testing.assert_close(cached, full, atol=0.08, rtol=0.03)
|
| 63 |
+
report = {
|
| 64 |
+
"device": torch.cuda.get_device_name(0),
|
| 65 |
+
"compute_capability": torch.cuda.get_device_capability(0),
|
| 66 |
+
"parameters": sum(parameter.numel() for parameter in model.parameters()),
|
| 67 |
+
"loss": float(output.loss.detach()),
|
| 68 |
+
"grad_norm": float(grad_norm.detach()),
|
| 69 |
+
"peak_gib": torch.cuda.max_memory_allocated() / 2**30,
|
| 70 |
+
"cache_max_abs_error": float((cached - full).abs().max()),
|
| 71 |
+
}
|
| 72 |
+
print(json.dumps(report, indent=2))
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
if __name__ == "__main__":
|
| 76 |
+
main()
|