Text Generation
Transformers
English
transwave_meyer
causal-lm
byte-level
raw-byte
attention-free
meyer
wavelet
custom_code
Instructions to use Angshul/TransWave with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Angshul/TransWave with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="Angshul/TransWave", trust_remote_code=True)# pip install -U transformers accelerate # Load model directly from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("Angshul/TransWave", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use Angshul/TransWave with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "Angshul/TransWave" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Angshul/TransWave", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/Angshul/TransWave
- SGLang
How to use Angshul/TransWave with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "Angshul/TransWave" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Angshul/TransWave", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "Angshul/TransWave" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Angshul/TransWave", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use Angshul/TransWave with Docker Model Runner:
docker model run hf.co/Angshul/TransWave
Download modeling_transwave.py from Angshul/TransWave: direct link, hf CLI and curl.
- Browser
- Download file 9.06 kB
-
https://huggingface.co/Angshul/TransWave/resolve/main/modeling_transwave.py
- Command line
-
hf download hf://Angshul/TransWave/modeling_transwave.py
-
curl -L -o modeling_transwave.py https://huggingface.co/Angshul/TransWave/resolve/main/modeling_transwave.py
9.06 kB
| from __future__ import annotations | |
| import os | |
| import torch | |
| import torch.nn.functional as F | |
| from huggingface_hub import hf_hub_download | |
| from transformers import PreTrainedModel | |
| from transformers.modeling_outputs import CausalLMOutput | |
| try: | |
| from .configuration_transwave import TransWaveConfig | |
| from .transwave_core import ( | |
| CTWModel, | |
| BYTE_VOCAB, | |
| BYTE_DIM, | |
| BYTES_PER_BLOCK, | |
| BYTE_DECODER_DIM, | |
| ) | |
| except ImportError: | |
| from configuration_transwave import TransWaveConfig | |
| from transwave_core import ( | |
| CTWModel, | |
| BYTE_VOCAB, | |
| BYTE_DIM, | |
| BYTES_PER_BLOCK, | |
| BYTE_DECODER_DIM, | |
| ) | |
| EXPECTED_PARAMS = 96_130_040 | |
| class TransWaveForCausalLM(PreTrainedModel): | |
| config_class = TransWaveConfig | |
| base_model_prefix = "transwave" | |
| main_input_name = "input_ids" | |
| _tied_weights_keys = ["transwave.decoder.shared_embedding.weight"] | |
| def __init__(self, config): | |
| super().__init__(config) | |
| self.transwave = CTWModel() | |
| # Do not call post_init(): CTWModel already performs the architecture's | |
| # exact initialization. The trained checkpoint is loaded afterwards. | |
| def get_input_embeddings(self): | |
| return self.transwave.tokenizer.byte_embedding | |
| def set_input_embeddings(self, value): | |
| self.transwave.tokenizer.byte_embedding = value | |
| self.transwave.decoder.shared_embedding = value | |
| def get_output_embeddings(self): | |
| return self.transwave.decoder.shared_embedding | |
| def from_pretrained(cls, pretrained_model_name_or_path, *model_args, **kwargs): | |
| config = kwargs.pop("config", None) | |
| revision = kwargs.pop("revision", None) | |
| cache_dir = kwargs.pop("cache_dir", None) | |
| token = kwargs.pop("token", None) | |
| local_files_only = kwargs.pop("local_files_only", False) | |
| torch_dtype = kwargs.pop("torch_dtype", None) | |
| kwargs.pop("trust_remote_code", None) | |
| kwargs.pop("use_safetensors", None) | |
| if config is None: | |
| config = TransWaveConfig.from_pretrained( | |
| pretrained_model_name_or_path, | |
| revision=revision, | |
| cache_dir=cache_dir, | |
| token=token, | |
| local_files_only=local_files_only, | |
| ) | |
| model = cls(config) | |
| path = os.fspath(pretrained_model_name_or_path) | |
| if os.path.isdir(path): | |
| ckpt_path = os.path.join(path, "best_model.pt") | |
| else: | |
| ckpt_path = hf_hub_download( | |
| repo_id=path, | |
| filename="best_model.pt", | |
| revision=revision, | |
| cache_dir=cache_dir, | |
| token=token, | |
| local_files_only=local_files_only, | |
| ) | |
| checkpoint = torch.load( | |
| ckpt_path, | |
| map_location="cpu", | |
| weights_only=False, | |
| ) | |
| state = checkpoint["model"] if isinstance(checkpoint, dict) and "model" in checkpoint else checkpoint | |
| incompatible = model.transwave.load_state_dict(state, strict=True) | |
| if incompatible.missing_keys or incompatible.unexpected_keys: | |
| raise RuntimeError( | |
| f"Checkpoint mismatch. Missing={incompatible.missing_keys}, " | |
| f"unexpected={incompatible.unexpected_keys}" | |
| ) | |
| n_params = sum(p.numel() for p in model.transwave.parameters()) | |
| if n_params != EXPECTED_PARAMS: | |
| raise RuntimeError(f"Parameter count {n_params:,} != {EXPECTED_PARAMS:,}") | |
| if torch_dtype not in (None, "auto"): | |
| model = model.to(dtype=torch_dtype) | |
| model.eval() | |
| return model | |
| def nll(self, input_ids, checkpoint_layers=False): | |
| return self.transwave.nll( | |
| input_ids, | |
| checkpoint_layers=checkpoint_layers, | |
| ) | |
| def contexts(self, input_ids, checkpoint_layers=False): | |
| return self.transwave.contexts( | |
| input_ids, | |
| checkpoint_layers=checkpoint_layers, | |
| ) | |
| def teacher_forced_logits(self, input_ids): | |
| context, target_blocks = self.transwave.contexts( | |
| input_ids, | |
| checkpoint_layers=False, | |
| ) | |
| decoder = self.transwave.decoder | |
| batch, blocks, _ = context.shape | |
| n = batch * blocks | |
| hidden = torch.tanh( | |
| decoder.context_proj(context) | |
| ).reshape(n, BYTE_DECODER_DIM) | |
| previous = decoder.bos[None, :].expand(n, -1) | |
| position_logits = [] | |
| for r in range(BYTES_PER_BLOCK): | |
| decoder_input = previous + decoder.byte_position[r][None, :] | |
| hidden = decoder.gru(decoder_input, hidden) | |
| z = decoder.to_byte_space(decoder.norm(hidden)) | |
| logits = F.linear(z, decoder.shared_embedding.weight) | |
| position_logits.append( | |
| logits.reshape(batch, blocks, BYTE_VOCAB) | |
| ) | |
| target = target_blocks[:, :, r].reshape(-1).long() | |
| previous = decoder.shared_embedding(target) | |
| logits = torch.stack(position_logits, dim=2) | |
| return logits.reshape( | |
| batch, | |
| blocks * BYTES_PER_BLOCK, | |
| BYTE_VOCAB, | |
| ) | |
| def forward( | |
| self, | |
| input_ids=None, | |
| labels=None, | |
| return_dict=None, | |
| **kwargs, | |
| ): | |
| if input_ids is None: | |
| raise ValueError("input_ids are required") | |
| if input_ids.ndim != 2: | |
| raise ValueError("input_ids must have shape [batch, tokens]") | |
| if input_ids.shape[1] % BYTES_PER_BLOCK != 0: | |
| raise ValueError("TransWave scoring length must be divisible by 8") | |
| if labels is not None: | |
| if labels.shape != input_ids.shape or not torch.equal(labels, input_ids): | |
| raise ValueError( | |
| "TransWave performs the causal shift internally; " | |
| "for exact scoring/training, labels must equal input_ids." | |
| ) | |
| logits = self.teacher_forced_logits(input_ids) | |
| loss = self.transwave.nll( | |
| input_ids, | |
| checkpoint_layers=False, | |
| ) | |
| if return_dict is False: | |
| return (loss, logits) | |
| return CausalLMOutput( | |
| loss=loss, | |
| logits=logits, | |
| ) | |
| def generate_bytes( | |
| self, | |
| input_ids, | |
| max_new_tokens=32, | |
| do_sample=False, | |
| temperature=1.0, | |
| top_k=None, | |
| ): | |
| if input_ids.ndim != 2 or input_ids.shape[0] != 1: | |
| raise ValueError("generate_bytes currently supports batch size 1") | |
| out = input_ids.long().clone() | |
| device = next(self.parameters()).device | |
| out = out.to(device) | |
| for _ in range(int(max_new_tokens)): | |
| total = out.shape[1] | |
| complete = (total // BYTES_PER_BLOCK) * BYTES_PER_BLOCK | |
| r = total - complete | |
| if complete == 0: | |
| block_context = self.transwave.bos_context[None, :].to(device) | |
| else: | |
| _, blocks = self.transwave.encode_completed_blocks( | |
| out[:, :complete], | |
| checkpoint_layers=False, | |
| ) | |
| h, _ = self.transwave.encode_completed_blocks( | |
| out[:, :complete], | |
| checkpoint_layers=False, | |
| ) | |
| block_context = h[:, -1, :] | |
| decoder = self.transwave.decoder | |
| hidden = torch.tanh(decoder.context_proj(block_context)) | |
| previous = decoder.bos[None, :] | |
| current = out[:, complete:] | |
| logits = None | |
| for j in range(r + 1): | |
| decoder_input = previous + decoder.byte_position[j][None, :] | |
| hidden = decoder.gru(decoder_input, hidden) | |
| z = decoder.to_byte_space(decoder.norm(hidden)) | |
| logits = F.linear(z, decoder.shared_embedding.weight) | |
| if j < r: | |
| previous = decoder.shared_embedding(current[:, j]) | |
| scores = logits.float() / max(float(temperature), 1e-6) | |
| if top_k is not None and int(top_k) > 0: | |
| k = min(int(top_k), BYTE_VOCAB) | |
| threshold = torch.topk(scores, k, dim=-1).values[:, -1:] | |
| scores = scores.masked_fill(scores < threshold, float("-inf")) | |
| if do_sample: | |
| next_id = torch.multinomial( | |
| torch.softmax(scores, dim=-1), | |
| num_samples=1, | |
| ) | |
| else: | |
| next_id = scores.argmax(dim=-1, keepdim=True) | |
| out = torch.cat([out, next_id], dim=1) | |
| return out |