LatentRoute / test_inference.py
Vchaudhari17's picture
Upload folder using huggingface_hub
e757d5e verified
Raw
History Blame Contribute Delete
4.63 kB
from __future__ import annotations
import argparse
import sys
from pathlib import Path
import torch
ROOT = Path(__file__).resolve().parents[1]
if str(ROOT) not in sys.path:
sys.path.insert(0, str(ROOT))
from src.model import LLM, ModelConfig
from src.tokenizer import BPETokenizer
from src.tokenizer.io_utils import load_tokenizer
def generate(model: LLM, input_ids: torch.Tensor, max_new_tokens: int, temperature: float = 1.0) -> torch.Tensor:
model.eval()
device = input_ids.device
current_ids = input_ids
# Setup initial cache
b, seq_len = current_ids.shape
_, caches = model(current_ids, use_cache=True)
generated = []
with torch.no_grad():
for _ in range(max_new_tokens):
# Pass only the last token, providing the cache
next_token_id = current_ids[:, -1:]
logits, caches = model(next_token_id, use_cache=True, caches=caches)
# Get last pos
next_token_logits = logits[:, -1, :] / temperature
probs = torch.nn.functional.softmax(next_token_logits, dim=-1)
next_token = torch.multinomial(probs, num_samples=1)
generated.append(next_token)
current_ids = torch.cat([current_ids, next_token], dim=1)
return torch.cat(generated, dim=1)
def main():
parser = argparse.ArgumentParser(description="Test model inference with text payload.")
parser.add_argument("--text", type=str, required=True, help="Input text payload")
parser.add_argument("--max_new_tokens", type=int, default=20, help="Number of tokens to generate")
parser.add_argument("--temperature", type=float, default=0.8, help="Sampling temperature")
parser.add_argument("--model_path", type=str, default="final_model.pt", help="Path to checkpoint")
parser.add_argument("--tokenizer_path", type=str, default="tokenizer_vocab.json", help="Path to tokenizer")
parser.add_argument("--d_model", type=int, default=512)
parser.add_argument("--n_layers", type=int, default=6)
parser.add_argument("--n_heads", type=int, default=8)
parser.add_argument("--max_seq_len", type=int, default=256)
parser.add_argument("--n_experts", type=int, default=8)
parser.add_argument("--d_c", type=int, default=64)
parser.add_argument("--d_rope", type=int, default=16)
args = parser.parse_args()
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Using device: {device}")
# 1. Initialize tokenizer
print(f"Loading tokenizer from {args.tokenizer_path}...")
if not Path(args.tokenizer_path).exists():
print("Tokenizer file not found!")
return
merges, vocab = load_tokenizer(args.tokenizer_path)
tokenizer = BPETokenizer()
tokenizer.merges = merges
tokenizer.vocab = vocab
vocab_size = len(tokenizer.vocab)
print(f"Tokenizer vocab size: {vocab_size}")
# 2. Initialize Model
print("Initializing model architecture...")
model = LLM(
vocab_size=vocab_size,
d_model=args.d_model,
n_layers=args.n_layers,
n_heads=args.n_heads,
d_c=args.d_c,
n_experts=args.n_experts,
max_seq_len=args.max_seq_len,
d_rope=args.d_rope,
).to(device)
if Path(args.model_path).exists():
print(f"Loading trained weights from {args.model_path}...")
model.load_state_dict(torch.load(args.model_path, map_location=device))
else:
print(f"Warning: {args.model_path} not found. Using untrained random weights.")
# 3. Process Input
tokens = tokenizer.encode(args.text)
token_ids = [tokenizer.vocab[t] for t in tokens if t in tokenizer.vocab]
if not token_ids:
print("Empty input after tokenization.")
return
input_tensor = torch.tensor([token_ids], dtype=torch.long, device=device)
print("\n--- Input payload ---")
print(args.text)
print(f"Tokens: {input_tensor.tolist()[0]}")
# 4. Generate
print("\n--- Generating ---")
out_tensor = generate(model, input_tensor, max_new_tokens=args.max_new_tokens, temperature=args.temperature)
out_ids = out_tensor[0].tolist()
# Decode back to text
out_tokens = [list(tokenizer.vocab.keys())[list(tokenizer.vocab.values()).index(idx)] for idx in out_ids]
decoded_text = tokenizer.decode(out_tokens)
print(decoded_text)
if not Path(args.model_path).exists():
print("\n(Note: The model is not trained yet, so the output is random text)")
if __name__ == "__main__":
main()