VDrontV2-Title / use.py
MishaGGG's picture
Update use.py
0d50b9b verified
Raw
History Blame Contribute Delete
5.42 kB
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
from threading import Thread
import re
MODEL_PATH = "VDrontV2-0.1b-Title"
TEMPERATURE = 0.4
MAX_NEW_TOKENS = 64
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
STOP_TOKENS = ["<|endoftext|>", "(end_title)", "(title)", "\n\n\n"]
STOP_PATTERNS = [
r"\(end_title\)",
r"\(title\)",
r"<\|endoftext\|>",
]
def load_model_and_tokenizer(model_path):
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=False)
model = AutoModelForCausalLM.from_pretrained(
model_path,
torch_dtype=torch.float16 if DEVICE == "cuda" else torch.float32,
device_map="auto",
trust_remote_code=False
)
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token
if tokenizer.eos_token is None:
tokenizer.eos_token = "<|endoftext|>"
tokenizer.eos_token_id = tokenizer.convert_tokens_to_ids("<|endoftext|>")
return model, tokenizer
def should_stop(text, accumulated_text=""):
full_text = accumulated_text + text
for stop_token in STOP_TOKENS:
if stop_token in full_text:
return True, full_text.split(stop_token)[0]
if len(full_text) > 100:
last_part = full_text[-50:]
if len(set(last_part.split())) <= 3:
return True, full_text
if len(full_text) > 60:
for i in range(10, 30):
pattern = full_text[-i:]
if full_text.count(pattern) > 3:
return True, full_text
return False, full_text
def generate_stream(model, tokenizer, prompt, temperature=0.4, max_new_tokens=256):
inputs = tokenizer(prompt, return_tensors="pt", truncation=True, max_length=2048)
inputs = {k: v.to(model.device) for k, v in inputs.items()}
streamer = TextIteratorStreamer(
tokenizer,
skip_prompt=True,
skip_special_tokens=False,
timeout=30.0
)
generation_kwargs = dict(
**inputs,
max_new_tokens=max_new_tokens,
temperature=temperature,
do_sample=True,
top_p=0.96,
repetition_penalty=1.15,
pad_token_id=tokenizer.pad_token_id,
eos_token_id=tokenizer.eos_token_id,
streamer=streamer,
)
thread = Thread(target=model.generate, kwargs=generation_kwargs)
thread.start()
accumulated_text = ""
try:
for new_text in streamer:
if new_text:
accumulated_text += new_text
stop, clean_text = should_stop(new_text,
accumulated_text[:-len(new_text)] if len(accumulated_text) > len(
new_text) else "")
if stop:
if clean_text and len(clean_text) > len(accumulated_text) - len(new_text):
yield clean_text
break
partial_stop = False
for stop_token in STOP_TOKENS:
for i in range(1, len(stop_token)):
if accumulated_text.endswith(stop_token[:i]):
partial_stop = True
break
if partial_stop:
break
if not partial_stop:
yield new_text
if len(accumulated_text) > 50 and len(accumulated_text.split()) > 10:
if any(pattern in accumulated_text for pattern in ["(end_title)", "(title)"]):
break
except Exception as e:
print(f"\n[Stream error: {e}]")
thread.join(timeout=5)
def text_continuation(model, tokenizer, temperature):
print(f"Instruct Mode (temp={temperature})")
print("Enter your text and the model will continue it.")
print("Commands: 'exit' or 'quit' — exit.")
print(f"Stop tokens: {', '.join(STOP_TOKENS)}")
print("=" * 60)
while True:
try:
user_input = input("\nUser: ").strip()
except (KeyboardInterrupt, EOFError):
print("\nGoodbye!")
break
if user_input.lower() in ["exit", "quit"]:
print("Goodbye!")
break
if not user_input:
continue
print("Title: ", end="", flush=True)
formatted_prompt = f"(user){user_input}(title)"
response_text = ""
for token in generate_stream(model, tokenizer, formatted_prompt, temperature=temperature,
max_new_tokens=MAX_NEW_TOKENS):
print(token, end="", flush=True)
response_text += token
if len(response_text.split()) > 50:
break
print()
if response_text:
print(f"[Generated {len(response_text.split())} words]")
if __name__ == "__main__":
print(f"Loading model from {MODEL_PATH}...")
model, tokenizer = load_model_and_tokenizer(MODEL_PATH)
print(f"Model loaded. Device: {DEVICE}")
print(f"Tokenizer eos_token: '{tokenizer.eos_token}'")
print(f"Tokenizer eos_token_id: {tokenizer.eos_token_id}")
text_continuation(model, tokenizer, temperature=TEMPERATURE)