AI / scripts /jarvis_pretrained_chat.py
shsplas's picture
Upload 15 files
c5f49b9 verified
Raw
History Blame Contribute Delete
5.83 kB
import argparse
import os
import time
import warnings
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
from transformers.utils import logging as hf_logging
os.environ.setdefault("HF_HUB_DISABLE_PROGRESS_BARS", "1")
os.environ.setdefault("HF_HUB_DISABLE_SYMLINKS_WARNING", "1")
hf_logging.disable_progress_bar()
hf_logging.set_verbosity_error()
def parse_args():
p = argparse.ArgumentParser(description="Pretrained Jarvis chat (CPU)")
p.add_argument("--model", default="Qwen/Qwen2.5-0.5B-Instruct")
p.add_argument("--temperature", type=float, default=0.4)
p.add_argument("--top-p", type=float, default=0.9)
p.add_argument("--top-k", type=int, default=40)
p.add_argument("--max-new-tokens", type=int, default=180)
p.add_argument("--max-history-turns", type=int, default=8)
p.add_argument("--repetition-penalty", type=float, default=1.08)
p.add_argument("--int8-dynamic", action="store_true")
p.add_argument("--low-cpu-mem-usage", action="store_true")
p.add_argument("--threads", type=int, default=max(1, min(6, (torch.get_num_threads() or 4))))
return p.parse_args()
def build_prompt(tokenizer, messages):
if hasattr(tokenizer, "apply_chat_template"):
try:
return tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True,
)
except Exception:
pass
# Fallback formatting if template is unavailable.
lines = []
for msg in messages:
role = msg.get("role", "user")
content = msg.get("content", "")
lines.append(f"{role.capitalize()}: {content}")
lines.append("Assistant:")
return "\n".join(lines)
def prepare_inputs(tokenizer, messages):
if hasattr(tokenizer, "apply_chat_template"):
try:
templated = tokenizer.apply_chat_template(
messages,
tokenize=True,
add_generation_prompt=True,
return_tensors="pt",
)
if isinstance(templated, dict):
return templated
return {
"input_ids": templated,
"attention_mask": torch.ones_like(templated),
}
except Exception:
pass
prompt = build_prompt(tokenizer, messages)
return tokenizer(prompt, return_tensors="pt")
@torch.inference_mode()
def generate_reply(model, tokenizer, messages, args):
model_device = next(model.parameters()).device
inputs = prepare_inputs(tokenizer, messages)
inputs = {k: v.to(model_device) for k, v in inputs.items()}
eos_id = tokenizer.eos_token_id
if eos_id is None:
eos_id = getattr(model.config, "eos_token_id", None)
pad_id = tokenizer.pad_token_id
if pad_id is None:
pad_id = eos_id if eos_id is not None else getattr(model.config, "pad_token_id", None)
effective_temp = max(float(args.temperature), 1e-5)
gen_kwargs = dict(
max_new_tokens=args.max_new_tokens,
repetition_penalty=args.repetition_penalty,
pad_token_id=pad_id,
eos_token_id=eos_id,
do_sample=True,
temperature=effective_temp,
top_p=args.top_p,
top_k=args.top_k,
)
output_ids = model.generate(
**inputs,
**gen_kwargs,
)
new_ids = output_ids[0, inputs["input_ids"].shape[1] :]
text = tokenizer.decode(new_ids, skip_special_tokens=True).strip()
return text
def main():
args = parse_args()
torch.set_num_threads(args.threads)
torch.set_num_interop_threads(1)
print(f"Loading model: {args.model}")
print(f"Threads: {torch.get_num_threads()}")
t0 = time.time()
tokenizer = AutoTokenizer.from_pretrained(args.model, use_fast=True)
if tokenizer.pad_token_id is None and tokenizer.eos_token_id is not None:
tokenizer.pad_token = tokenizer.eos_token
model_kwargs = {"low_cpu_mem_usage": args.low_cpu_mem_usage}
try:
model = AutoModelForCausalLM.from_pretrained(
args.model,
dtype=torch.float32,
**model_kwargs,
)
except TypeError:
model = AutoModelForCausalLM.from_pretrained(
args.model,
torch_dtype=torch.float32,
**model_kwargs,
)
model.eval()
if args.int8_dynamic:
print("Applying dynamic INT8 quantization...")
warnings.filterwarnings(
"ignore",
message="torch.ao.quantization is deprecated*",
category=DeprecationWarning,
)
try:
model = torch.ao.quantization.quantize_dynamic(
model,
{torch.nn.Linear},
dtype=torch.qint8,
)
model.eval()
except Exception as exc:
print(f"INT8 quantization skipped: {exc}")
print(f"Model ready in {(time.time() - t0):.1f}s")
print("Type 'exit' to quit.\n")
system_msg = {
"role": "system",
"content": (
"You are Jarvis, a concise and practical AI assistant. "
"Prefer clear, actionable answers."
),
}
history = [system_msg]
while True:
user = input("User: ").strip()
if user.lower() in {"exit", "quit"}:
break
if not user:
continue
history.append({"role": "user", "content": user})
# Keep context bounded for CPU latency.
if len(history) > 1 + (args.max_history_turns * 2):
history = [system_msg] + history[-(args.max_history_turns * 2) :]
reply = generate_reply(model, tokenizer, history, args)
print(f"Assistant: {reply}\n")
history.append({"role": "assistant", "content": reply})
if __name__ == "__main__":
main()