clyxbox 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- clyxbox-0.2.0/PKG-INFO +12 -0
- clyxbox-0.2.0/clyxbox/__init__.py +5 -0
- clyxbox-0.2.0/clyxbox/model.py +311 -0
- clyxbox-0.2.0/clyxbox/tokenizer.py +77 -0
- clyxbox-0.2.0/clyxbox.egg-info/PKG-INFO +12 -0
- clyxbox-0.2.0/clyxbox.egg-info/SOURCES.txt +9 -0
- clyxbox-0.2.0/clyxbox.egg-info/dependency_links.txt +1 -0
- clyxbox-0.2.0/clyxbox.egg-info/requires.txt +4 -0
- clyxbox-0.2.0/clyxbox.egg-info/top_level.txt +1 -0
- clyxbox-0.2.0/pyproject.toml +24 -0
- clyxbox-0.2.0/setup.cfg +4 -0
clyxbox-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: clyxbox
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Inference library for Clyx language models
|
|
5
|
+
License: Apache-2.0
|
|
6
|
+
Project-URL: Homepage, https://huggingface.co/syntropic-clx
|
|
7
|
+
Requires-Python: >=3.9
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: torch>=2.0
|
|
10
|
+
Requires-Dist: tokenizers>=0.19
|
|
11
|
+
Requires-Dist: huggingface_hub>=0.23
|
|
12
|
+
Requires-Dist: safetensors>=0.4
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import math
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import List, Optional, Tuple, Union
|
|
5
|
+
|
|
6
|
+
import torch
|
|
7
|
+
import torch.nn as nn
|
|
8
|
+
import torch.nn.functional as F
|
|
9
|
+
import torch.utils.checkpoint as checkpoint_utils
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# ── Config ────────────────────────────────────────────────────────────────────
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class ModelConfig:
|
|
16
|
+
vocab_size: int = 32000
|
|
17
|
+
hidden_size: int = 768
|
|
18
|
+
num_layers: int = 12
|
|
19
|
+
num_heads: int = 12
|
|
20
|
+
max_position_embeddings: int = 2048
|
|
21
|
+
intermediate_size: int = 2048
|
|
22
|
+
norm_eps: float = 1e-6
|
|
23
|
+
attn_dropout: float = 0.0
|
|
24
|
+
resid_dropout: float = 0.0
|
|
25
|
+
tie_word_embeddings: bool = True
|
|
26
|
+
gradient_checkpointing: bool = False
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# ── Architecture ──────────────────────────────────────────────────────────────
|
|
30
|
+
|
|
31
|
+
class RMSNorm(nn.Module):
|
|
32
|
+
def __init__(self, dim: int, eps: float = 1e-6):
|
|
33
|
+
super().__init__()
|
|
34
|
+
self.eps = eps
|
|
35
|
+
self.weight = nn.Parameter(torch.ones(dim))
|
|
36
|
+
|
|
37
|
+
def forward(self, x):
|
|
38
|
+
return x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + self.eps) * self.weight
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class RotaryEmbedding(nn.Module):
|
|
42
|
+
def __init__(self, dim, max_position_embeddings=2048, base=10000, device=None):
|
|
43
|
+
super().__init__()
|
|
44
|
+
self.dim = dim
|
|
45
|
+
self.base = base
|
|
46
|
+
self.max_position_embeddings = max_position_embeddings
|
|
47
|
+
inv_freq = 1.0 / (base ** (torch.arange(0, dim, 2).float().to(device) / dim))
|
|
48
|
+
self.register_buffer("inv_freq", inv_freq, persistent=False)
|
|
49
|
+
self._set_cos_sin_cache(max_position_embeddings, device=device, dtype=torch.get_default_dtype())
|
|
50
|
+
|
|
51
|
+
def _set_cos_sin_cache(self, seq_len, device, dtype):
|
|
52
|
+
self.max_seq_len_cached = seq_len
|
|
53
|
+
t = torch.arange(seq_len, device=device, dtype=self.inv_freq.dtype)
|
|
54
|
+
freqs = torch.outer(t, self.inv_freq)
|
|
55
|
+
emb = torch.cat((freqs, freqs), dim=-1)
|
|
56
|
+
self.register_buffer("cos_cached", emb.cos().to(dtype), persistent=False)
|
|
57
|
+
self.register_buffer("sin_cached", emb.sin().to(dtype), persistent=False)
|
|
58
|
+
|
|
59
|
+
def forward(self, x, seq_len):
|
|
60
|
+
if seq_len > self.max_seq_len_cached or self.cos_cached.device != x.device:
|
|
61
|
+
self._set_cos_sin_cache(seq_len, device=x.device, dtype=x.dtype)
|
|
62
|
+
return self.cos_cached[:seq_len].to(dtype=x.dtype), self.sin_cached[:seq_len].to(dtype=x.dtype)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def rotate_half(x):
|
|
66
|
+
x1 = x[..., : x.shape[-1] // 2]
|
|
67
|
+
x2 = x[..., x.shape[-1] // 2 :]
|
|
68
|
+
return torch.cat((-x2, x1), dim=-1)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def apply_rotary_pos_emb(q, k, cos, sin, position_ids):
|
|
72
|
+
cos = cos[position_ids].unsqueeze(1)
|
|
73
|
+
sin = sin[position_ids].unsqueeze(1)
|
|
74
|
+
return (q * cos) + (rotate_half(q) * sin), (k * cos) + (rotate_half(k) * sin)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class CausalSelfAttention(nn.Module):
|
|
78
|
+
def __init__(self, config: ModelConfig):
|
|
79
|
+
super().__init__()
|
|
80
|
+
self.num_heads = config.num_heads
|
|
81
|
+
self.head_dim = config.hidden_size // config.num_heads
|
|
82
|
+
self.q_proj = nn.Linear(config.hidden_size, config.hidden_size, bias=False)
|
|
83
|
+
self.k_proj = nn.Linear(config.hidden_size, config.hidden_size, bias=False)
|
|
84
|
+
self.v_proj = nn.Linear(config.hidden_size, config.hidden_size, bias=False)
|
|
85
|
+
self.out_proj = nn.Linear(config.hidden_size, config.hidden_size, bias=False)
|
|
86
|
+
self.attn_dropout = config.attn_dropout
|
|
87
|
+
self.resid_dropout = nn.Dropout(config.resid_dropout)
|
|
88
|
+
|
|
89
|
+
def forward(self, x, rotary_emb, position_ids, attn_mask=None, past_key_value=None, use_cache=False):
|
|
90
|
+
bsz, seq_len, hidden = x.size()
|
|
91
|
+
q = self.q_proj(x).view(bsz, seq_len, self.num_heads, self.head_dim).transpose(1, 2)
|
|
92
|
+
k = self.k_proj(x).view(bsz, seq_len, self.num_heads, self.head_dim).transpose(1, 2)
|
|
93
|
+
v = self.v_proj(x).view(bsz, seq_len, self.num_heads, self.head_dim).transpose(1, 2)
|
|
94
|
+
|
|
95
|
+
max_pos = int(position_ids.max().item()) + 1
|
|
96
|
+
cos, sin = rotary_emb(q, seq_len=max_pos)
|
|
97
|
+
q, k = apply_rotary_pos_emb(q, k, cos, sin, position_ids)
|
|
98
|
+
|
|
99
|
+
if past_key_value is not None:
|
|
100
|
+
prev_k, prev_v = past_key_value
|
|
101
|
+
k = torch.cat([prev_k, k], dim=2)
|
|
102
|
+
v = torch.cat([prev_v, v], dim=2)
|
|
103
|
+
|
|
104
|
+
new_kv = (k, v) if use_cache else None
|
|
105
|
+
is_causal = attn_mask is None and seq_len > 1
|
|
106
|
+
y = F.scaled_dot_product_attention(
|
|
107
|
+
q, k, v,
|
|
108
|
+
attn_mask=attn_mask,
|
|
109
|
+
dropout_p=self.attn_dropout if self.training else 0.0,
|
|
110
|
+
is_causal=is_causal,
|
|
111
|
+
)
|
|
112
|
+
y = y.transpose(1, 2).contiguous().view(bsz, seq_len, hidden)
|
|
113
|
+
return self.resid_dropout(self.out_proj(y)), new_kv
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class SwiGLUMLP(nn.Module):
|
|
117
|
+
def __init__(self, config: ModelConfig):
|
|
118
|
+
super().__init__()
|
|
119
|
+
self.w1 = nn.Linear(config.hidden_size, config.intermediate_size, bias=False)
|
|
120
|
+
self.w2 = nn.Linear(config.hidden_size, config.intermediate_size, bias=False)
|
|
121
|
+
self.w3 = nn.Linear(config.intermediate_size, config.hidden_size, bias=False)
|
|
122
|
+
self.dropout = nn.Dropout(config.resid_dropout)
|
|
123
|
+
|
|
124
|
+
def forward(self, x):
|
|
125
|
+
return self.dropout(self.w3(F.silu(self.w1(x)) * self.w2(x)))
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class TransformerBlock(nn.Module):
|
|
129
|
+
def __init__(self, config: ModelConfig):
|
|
130
|
+
super().__init__()
|
|
131
|
+
self.attn_norm = RMSNorm(config.hidden_size, eps=config.norm_eps)
|
|
132
|
+
self.attn = CausalSelfAttention(config)
|
|
133
|
+
self.mlp_norm = RMSNorm(config.hidden_size, eps=config.norm_eps)
|
|
134
|
+
self.mlp = SwiGLUMLP(config)
|
|
135
|
+
|
|
136
|
+
def forward(self, x, rotary_emb, position_ids, attn_mask=None, past_key_value=None, use_cache=False):
|
|
137
|
+
residual = x
|
|
138
|
+
attn_out, new_kv = self.attn(
|
|
139
|
+
self.attn_norm(x), rotary_emb, position_ids,
|
|
140
|
+
attn_mask=attn_mask, past_key_value=past_key_value, use_cache=use_cache,
|
|
141
|
+
)
|
|
142
|
+
x = residual + attn_out
|
|
143
|
+
x = x + self.mlp(self.mlp_norm(x))
|
|
144
|
+
return x, new_kv
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class _CoreTransformer(nn.Module):
|
|
148
|
+
"""Internal transformer — matches the checkpoint keys exactly."""
|
|
149
|
+
def __init__(self, config: ModelConfig):
|
|
150
|
+
super().__init__()
|
|
151
|
+
self.config = config
|
|
152
|
+
self.embed = nn.Embedding(config.vocab_size, config.hidden_size)
|
|
153
|
+
self.rotary_emb = RotaryEmbedding(
|
|
154
|
+
dim=config.hidden_size // config.num_heads,
|
|
155
|
+
max_position_embeddings=config.max_position_embeddings,
|
|
156
|
+
)
|
|
157
|
+
self.layers = nn.ModuleList([TransformerBlock(config) for _ in range(config.num_layers)])
|
|
158
|
+
self.norm = RMSNorm(config.hidden_size, eps=config.norm_eps)
|
|
159
|
+
self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
|
|
160
|
+
if config.tie_word_embeddings:
|
|
161
|
+
self.lm_head.weight = self.embed.weight
|
|
162
|
+
|
|
163
|
+
def forward(self, input_ids, position_ids=None, past_key_values=None, use_cache=False):
|
|
164
|
+
bsz, seq_len = input_ids.size()
|
|
165
|
+
if position_ids is None:
|
|
166
|
+
past_len = past_key_values[0][0].size(2) if past_key_values else 0
|
|
167
|
+
position_ids = torch.arange(past_len, past_len + seq_len, dtype=torch.long, device=input_ids.device)
|
|
168
|
+
position_ids = position_ids.unsqueeze(0).expand(bsz, -1)
|
|
169
|
+
|
|
170
|
+
x = self.embed(input_ids)
|
|
171
|
+
new_kvs = []
|
|
172
|
+
for idx, block in enumerate(self.layers):
|
|
173
|
+
past_kv = past_key_values[idx] if past_key_values else None
|
|
174
|
+
x, new_kv = block(x, self.rotary_emb, position_ids, past_key_value=past_kv, use_cache=use_cache)
|
|
175
|
+
new_kvs.append(new_kv)
|
|
176
|
+
|
|
177
|
+
x = self.norm(x)
|
|
178
|
+
logits = self.lm_head(x)
|
|
179
|
+
return logits, new_kvs
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
# ── Public API ────────────────────────────────────────────────────────────────
|
|
183
|
+
|
|
184
|
+
class ClyxModel(nn.Module):
|
|
185
|
+
"""
|
|
186
|
+
Clyx causal language model — ready for inference.
|
|
187
|
+
|
|
188
|
+
Usage:
|
|
189
|
+
model = ClyxModel.from_pretrained("syntropic-clx/Clyx_0.2-115.67M-BASE")
|
|
190
|
+
model.eval()
|
|
191
|
+
"""
|
|
192
|
+
|
|
193
|
+
def __init__(self, config: ModelConfig):
|
|
194
|
+
super().__init__()
|
|
195
|
+
self.config = config
|
|
196
|
+
self._model = _CoreTransformer(config)
|
|
197
|
+
|
|
198
|
+
# ── from_pretrained ──────────────────────────────────────────────────────
|
|
199
|
+
|
|
200
|
+
@classmethod
|
|
201
|
+
def from_pretrained(cls, repo_id: str, device: Optional[str] = None, token: Optional[str] = None):
|
|
202
|
+
"""Load a Clyx model from a HuggingFace Hub repository."""
|
|
203
|
+
try:
|
|
204
|
+
from huggingface_hub import hf_hub_download
|
|
205
|
+
except ImportError:
|
|
206
|
+
raise ImportError("pip install huggingface_hub")
|
|
207
|
+
try:
|
|
208
|
+
from safetensors.torch import load_file
|
|
209
|
+
except ImportError:
|
|
210
|
+
raise ImportError("pip install safetensors")
|
|
211
|
+
|
|
212
|
+
if device is None:
|
|
213
|
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
|
214
|
+
|
|
215
|
+
# Load config
|
|
216
|
+
cfg_path = hf_hub_download(repo_id=repo_id, filename="config.json", token=token)
|
|
217
|
+
with open(cfg_path) as f:
|
|
218
|
+
raw = json.load(f)
|
|
219
|
+
|
|
220
|
+
# Map HF config keys → ModelConfig fields
|
|
221
|
+
field_map = {
|
|
222
|
+
"hidden_size": "hidden_size",
|
|
223
|
+
"num_hidden_layers": "num_layers",
|
|
224
|
+
"num_attention_heads": "num_heads",
|
|
225
|
+
"max_position_embeddings": "max_position_embeddings",
|
|
226
|
+
"intermediate_size": "intermediate_size",
|
|
227
|
+
"rms_norm_eps": "norm_eps",
|
|
228
|
+
"vocab_size": "vocab_size",
|
|
229
|
+
"tie_word_embeddings": "tie_word_embeddings",
|
|
230
|
+
}
|
|
231
|
+
cfg_kwargs = {}
|
|
232
|
+
for hf_key, our_key in field_map.items():
|
|
233
|
+
if hf_key in raw:
|
|
234
|
+
cfg_kwargs[our_key] = raw[hf_key]
|
|
235
|
+
elif our_key in raw:
|
|
236
|
+
cfg_kwargs[our_key] = raw[our_key]
|
|
237
|
+
|
|
238
|
+
config = ModelConfig(**cfg_kwargs)
|
|
239
|
+
model = cls(config)
|
|
240
|
+
|
|
241
|
+
# Load weights
|
|
242
|
+
weights_path = hf_hub_download(repo_id=repo_id, filename="model.safetensors", token=token)
|
|
243
|
+
state = load_file(weights_path, device=device)
|
|
244
|
+
model._model.load_state_dict(state, strict=True)
|
|
245
|
+
model = model.to(device)
|
|
246
|
+
return model
|
|
247
|
+
|
|
248
|
+
# ── forward ──────────────────────────────────────────────────────────────
|
|
249
|
+
|
|
250
|
+
def forward(self, input_ids, **kwargs):
|
|
251
|
+
return self._model(input_ids, **kwargs)
|
|
252
|
+
|
|
253
|
+
# ── generate ─────────────────────────────────────────────────────────────
|
|
254
|
+
|
|
255
|
+
@torch.no_grad()
|
|
256
|
+
def generate(
|
|
257
|
+
self,
|
|
258
|
+
input_ids: torch.Tensor,
|
|
259
|
+
max_new_tokens: int = 200,
|
|
260
|
+
temperature: float = 1.0,
|
|
261
|
+
top_p: float = 1.0,
|
|
262
|
+
top_k: int = 0,
|
|
263
|
+
repetition_penalty: float = 1.0,
|
|
264
|
+
eos_token_id: Optional[int] = None,
|
|
265
|
+
) -> torch.Tensor:
|
|
266
|
+
"""Auto-regressive generation with temperature / top-p / top-k / repetition penalty."""
|
|
267
|
+
device = next(self.parameters()).device
|
|
268
|
+
ids = input_ids.to(device)
|
|
269
|
+
past_key_values = None
|
|
270
|
+
|
|
271
|
+
for _ in range(max_new_tokens):
|
|
272
|
+
# On the first step pass the full prompt; after that pass only the new token
|
|
273
|
+
cur_input = ids if past_key_values is None else ids[:, -1:]
|
|
274
|
+
logits, past_key_values = self._model(cur_input, past_key_values=past_key_values, use_cache=True)
|
|
275
|
+
next_logits = logits[:, -1, :] # (B, vocab)
|
|
276
|
+
|
|
277
|
+
# Repetition penalty
|
|
278
|
+
if repetition_penalty != 1.0:
|
|
279
|
+
for b in range(ids.size(0)):
|
|
280
|
+
unique = ids[b].unique()
|
|
281
|
+
next_logits[b, unique] = torch.where(
|
|
282
|
+
next_logits[b, unique] < 0,
|
|
283
|
+
next_logits[b, unique] * repetition_penalty,
|
|
284
|
+
next_logits[b, unique] / repetition_penalty,
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
# Temperature
|
|
288
|
+
if temperature != 1.0:
|
|
289
|
+
next_logits = next_logits / temperature
|
|
290
|
+
|
|
291
|
+
# Top-k
|
|
292
|
+
if top_k > 0:
|
|
293
|
+
topk_vals = torch.topk(next_logits, top_k).values[:, -1, None]
|
|
294
|
+
next_logits = next_logits.masked_fill(next_logits < topk_vals, float("-inf"))
|
|
295
|
+
|
|
296
|
+
# Top-p (nucleus)
|
|
297
|
+
if top_p < 1.0:
|
|
298
|
+
sorted_logits, sorted_idx = torch.sort(next_logits, descending=True)
|
|
299
|
+
cum_probs = torch.cumsum(F.softmax(sorted_logits, dim=-1), dim=-1)
|
|
300
|
+
remove = cum_probs - F.softmax(sorted_logits, dim=-1) > top_p
|
|
301
|
+
sorted_logits[remove] = float("-inf")
|
|
302
|
+
next_logits = torch.zeros_like(next_logits).scatter(1, sorted_idx, sorted_logits)
|
|
303
|
+
|
|
304
|
+
probs = F.softmax(next_logits, dim=-1)
|
|
305
|
+
next_token = torch.multinomial(probs, num_samples=1)
|
|
306
|
+
ids = torch.cat([ids, next_token], dim=1)
|
|
307
|
+
|
|
308
|
+
if eos_token_id is not None and (next_token == eos_token_id).all():
|
|
309
|
+
break
|
|
310
|
+
|
|
311
|
+
return ids
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from typing import List, Optional, Union
|
|
2
|
+
|
|
3
|
+
import torch
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
SPECIAL_TOKENS = {
|
|
7
|
+
"PAD": "<PAD>", "UNK": "<UNK>", "BOS": "<BOS>", "EOS": "<EOS>",
|
|
8
|
+
"USER": "<USER>", "USER_END": "</USER>", "MODEL": "<MODEL>", "MODEL_END": "</MODEL>",
|
|
9
|
+
"STOP": "<STOP>", "SYSTEM": "<SYSTEM>", "SYSTEM_END": "</SYSTEM>",
|
|
10
|
+
"MEMORY": "<MEMORY>", "MEMORY_END": "</MEMORY>",
|
|
11
|
+
"TOOL_CALL": "<TOOL_CALL>", "TOOL_CALL_END": "</TOOL_CALL>",
|
|
12
|
+
"TOOL_RESULT": "<TOOL_RESULT>", "TOOL_RESULT_END": "</TOOL_RESULT>",
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ClyxTokenizer:
|
|
17
|
+
"""
|
|
18
|
+
Clyx tokenizer backed by a ByteLevel BPE tokenizer.json.
|
|
19
|
+
|
|
20
|
+
Usage:
|
|
21
|
+
tok = ClyxTokenizer.from_pretrained("syntropic-clx/Clyx_0.2-115.67M-BASE")
|
|
22
|
+
ids = tok.encode("Hello world", return_tensors="pt")
|
|
23
|
+
text = tok.decode(ids[0])
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(self, tokenizer):
|
|
27
|
+
self._tok = tokenizer
|
|
28
|
+
for name, token in SPECIAL_TOKENS.items():
|
|
29
|
+
setattr(self, f"{name.lower()}_id", tokenizer.token_to_id(token))
|
|
30
|
+
|
|
31
|
+
# ── from_pretrained ──────────────────────────────────────────────────────
|
|
32
|
+
|
|
33
|
+
@classmethod
|
|
34
|
+
def from_pretrained(cls, repo_id: str, token: Optional[str] = None):
|
|
35
|
+
"""Load tokenizer from a HuggingFace Hub repository."""
|
|
36
|
+
try:
|
|
37
|
+
from huggingface_hub import hf_hub_download
|
|
38
|
+
except ImportError:
|
|
39
|
+
raise ImportError("pip install huggingface_hub")
|
|
40
|
+
try:
|
|
41
|
+
from tokenizers import Tokenizer
|
|
42
|
+
except ImportError:
|
|
43
|
+
raise ImportError("pip install tokenizers")
|
|
44
|
+
|
|
45
|
+
path = hf_hub_download(repo_id=repo_id, filename="tokenizer.json", token=token)
|
|
46
|
+
return cls(Tokenizer.from_file(path))
|
|
47
|
+
|
|
48
|
+
# ── encode / decode ──────────────────────────────────────────────────────
|
|
49
|
+
|
|
50
|
+
def encode(
|
|
51
|
+
self,
|
|
52
|
+
text: str,
|
|
53
|
+
add_special_tokens: bool = False,
|
|
54
|
+
return_tensors: Optional[str] = None,
|
|
55
|
+
) -> Union[List[int], torch.Tensor]:
|
|
56
|
+
ids = self._tok.encode(text).ids
|
|
57
|
+
if add_special_tokens:
|
|
58
|
+
ids = [self.bos_id] + ids + [self.eos_id]
|
|
59
|
+
if return_tensors == "pt":
|
|
60
|
+
return torch.tensor([ids], dtype=torch.long)
|
|
61
|
+
return ids
|
|
62
|
+
|
|
63
|
+
def decode(
|
|
64
|
+
self,
|
|
65
|
+
ids: Union[List[int], torch.Tensor],
|
|
66
|
+
skip_special_tokens: bool = True,
|
|
67
|
+
) -> str:
|
|
68
|
+
if isinstance(ids, torch.Tensor):
|
|
69
|
+
ids = ids.detach().cpu().tolist()
|
|
70
|
+
return self._tok.decode([int(x) for x in ids], skip_special_tokens=skip_special_tokens)
|
|
71
|
+
|
|
72
|
+
def __call__(self, text: str, **kwargs):
|
|
73
|
+
return self.encode(text, **kwargs)
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
def vocab_size(self) -> int:
|
|
77
|
+
return self._tok.get_vocab_size()
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: clyxbox
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Inference library for Clyx language models
|
|
5
|
+
License: Apache-2.0
|
|
6
|
+
Project-URL: Homepage, https://huggingface.co/syntropic-clx
|
|
7
|
+
Requires-Python: >=3.9
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: torch>=2.0
|
|
10
|
+
Requires-Dist: tokenizers>=0.19
|
|
11
|
+
Requires-Dist: huggingface_hub>=0.23
|
|
12
|
+
Requires-Dist: safetensors>=0.4
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
clyxbox
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "clyxbox"
|
|
7
|
+
version = "0.2.0"
|
|
8
|
+
description = "Inference library for Clyx language models"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "Apache-2.0" }
|
|
11
|
+
requires-python = ">=3.9"
|
|
12
|
+
dependencies = [
|
|
13
|
+
"torch>=2.0",
|
|
14
|
+
"tokenizers>=0.19",
|
|
15
|
+
"huggingface_hub>=0.23",
|
|
16
|
+
"safetensors>=0.4",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[project.urls]
|
|
20
|
+
Homepage = "https://huggingface.co/syntropic-clx"
|
|
21
|
+
|
|
22
|
+
[tool.setuptools.packages.find]
|
|
23
|
+
where = ["."]
|
|
24
|
+
include = ["clyxbox*"]
|
clyxbox-0.2.0/setup.cfg
ADDED