Download generate.py from AmauryLC/ys: direct link, hf CLI and curl.
- Browser
- Download file 2.68 kB
-
https://huggingface.co/AmauryLC/ys/resolve/main/generate.py
- Command line
-
hf download hf://AmauryLC/ys/generate.py
-
curl -L -o generate.py https://huggingface.co/AmauryLC/ys/resolve/main/generate.py
2.68 kB
| import argparse | |
| import json | |
| from pathlib import Path | |
| import torch | |
| import tiktoken | |
| from safetensors.torch import load_file | |
| from modeling_ys import GPTModel | |
| TOKENIZER_VOCAB_SIZE = 50257 | |
| END_OF_TEXT_ID = 50256 | |
| def main(): | |
| parser = argparse.ArgumentParser(description="Génère du texte avec Ys.") | |
| parser.add_argument("--prompt", default="Il était une fois") | |
| parser.add_argument("--max-new-tokens", type=int, default=120) | |
| parser.add_argument("--temperature", type=float, default=0.8, | |
| help="0 pour choisir le token le plus probable") | |
| parser.add_argument("--top-k", type=int, default=40, | |
| help="0 pour désactiver le filtrage top-k") | |
| parser.add_argument("--device", choices=("auto", "cpu", "cuda"), default="auto") | |
| args = parser.parse_args() | |
| repo_dir = Path(__file__).resolve().parent | |
| config = json.loads((repo_dir / "config.json").read_text(encoding="utf-8")) | |
| device = args.device | |
| if device == "auto": | |
| device = "cuda" if torch.cuda.is_available() else "cpu" | |
| if device == "cuda" and not torch.cuda.is_available(): | |
| raise SystemExit("CUDA n'est pas disponible. Relance avec --device cpu.") | |
| if args.temperature < 0: | |
| raise SystemExit("--temperature doit être positif ou égal à 0.") | |
| model = GPTModel(config) | |
| state_dict = load_file(str(repo_dir / "model.safetensors"), device="cpu") | |
| model.load_state_dict(state_dict, strict=True) | |
| model.to(device).eval() | |
| tokenizer = tiktoken.get_encoding("gpt2") | |
| token_ids = torch.tensor([tokenizer.encode(args.prompt)], dtype=torch.long, device=device) | |
| if token_ids.shape[1] == 0: | |
| token_ids = torch.tensor([[END_OF_TEXT_ID]], dtype=torch.long, device=device) | |
| for _ in range(args.max_new_tokens): | |
| context = token_ids[:, -config["context_length"]:] | |
| with torch.inference_mode(): | |
| logits = model(context)[:, -1, :TOKENIZER_VOCAB_SIZE] | |
| if args.temperature == 0: | |
| next_id = torch.argmax(logits, dim=-1, keepdim=True) | |
| else: | |
| logits = logits / args.temperature | |
| if 0 < args.top_k < logits.shape[-1]: | |
| threshold = torch.topk(logits, args.top_k, dim=-1).values[:, -1, None] | |
| logits = logits.masked_fill(logits < threshold, float("-inf")) | |
| probabilities = torch.softmax(logits, dim=-1) | |
| next_id = torch.multinomial(probabilities, num_samples=1) | |
| if next_id.item() == END_OF_TEXT_ID: | |
| break | |
| token_ids = torch.cat((token_ids, next_id), dim=1) | |
| print(tokenizer.decode(token_ids[0].tolist())) | |
| if __name__ == "__main__": | |
| main() | |