"""Inference with LoRA adapter for ORTOS bot. Loads base model (pre-quantized 4-bit) + LoRA weights and answers questions. """ import torch from transformers import AutoModelForCausalLM, AutoTokenizer from peft import PeftModel MODEL_NAME = "unsloth/Meta-Llama-3.1-8B-bnb-4bit" LORA_PATH = "lora_ortos" def load_lora_model(): model = AutoModelForCausalLM.from_pretrained( MODEL_NAME, device_map="auto", dtype=torch.bfloat16, ) model = PeftModel.from_pretrained(model, LORA_PATH) tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME) tokenizer.pad_token = tokenizer.eos_token return model, tokenizer def ask(model, tokenizer, question: str) -> str: prompt = f"<|begin_of_text|><|start_header_id|>user<|end_header_id|>\n\n{question}<|eot_id|><|start_header_id|>assistant<|end_header_id|>\n\n" inputs = tokenizer([prompt], return_tensors="pt").to("cuda") outputs = model.generate(**inputs, max_new_tokens=256, temperature=0.3) response = tokenizer.decode(outputs[0], skip_special_tokens=False) parts = response.split("<|start_header_id|>assistant<|end_header_id|>") if len(parts) > 1: return parts[-1].replace("<|eot_id|>", "").strip() return response if __name__ == "__main__": model, tokenizer = load_lora_model() print("LoRA модель загружена. Пиши вопрос (или 'exit'):") while True: q = input("> ") if q.lower() == "exit": break print(ask(model, tokenizer, q)) print()