# Standalone Inference Cell Paste this as the **last cell** in Kaggle/Colab after training, or run it in a fresh notebook. It is independent of previous training cells. ## Configure paths Set: ```python BASE_MODEL_ID = "LiquidAI/LFM2.5-1.2B-Instruct" ADAPTER_PATH = "./lfm25-stable-qlora-cybersecurity-adapter" ``` For Unsloth-trained adapters, examples: ```python BASE_MODEL_ID = "unsloth/LFM2.5-1.2B-Instruct" ADAPTER_PATH = "./lfm25-lora-adapter" ``` ```python BASE_MODEL_ID = "unsloth/Qwen3-4B-Instruct-2507-unsloth-bnb-4bit" ADAPTER_PATH = "./qwen3-lora-adapter" ``` If you pushed adapter to Hub: ```python ADAPTER_PATH = "your-username/your-adapter-repo" ``` --- ## Complete independent cell ```python # ============================================================ # Standalone LoRA Adapter Inference / Chat Cell # Works in fresh Kaggle/Colab notebook too. # ============================================================ !pip install -q -U "transformers>=4.56.0" "peft>=0.18.0" "accelerate>=1.0.0" "bitsandbytes>=0.45.0" "huggingface_hub>=0.25.0" import torch from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig from peft import PeftModel # -------------------- CONFIG -------------------- # Use the SAME base model used during training. BASE_MODEL_ID = "LiquidAI/LFM2.5-1.2B-Instruct" # Local adapter folder OR HF repo id. # Common local paths: # ./lfm25-lora-adapter # ./qwen3-lora-adapter # ./gemma4-lora-adapter # ./lfm25-stable-qlora-cybersecurity-adapter ADAPTER_PATH = "./lfm25-stable-qlora-cybersecurity-adapter" LOAD_IN_4BIT = True MAX_NEW_TOKENS = 512 TEMPERATURE = 0.7 TOP_P = 0.9 SYSTEM_PROMPT = "You are a helpful assistant. For cybersecurity topics, provide ethical, defensive, authorized guidance only." # ------------------------------------------------ compute_dtype = torch.float16 bnb_config = None if LOAD_IN_4BIT: bnb_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_quant_type="nf4", bnb_4bit_use_double_quant=True, bnb_4bit_compute_dtype=compute_dtype, ) print("Loading tokenizer...") tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL_ID, trust_remote_code=True, use_fast=True) if tokenizer.pad_token is None: tokenizer.pad_token = tokenizer.eos_token tokenizer.padding_side = "right" print("Loading base model...") base_model = AutoModelForCausalLM.from_pretrained( BASE_MODEL_ID, quantization_config=bnb_config, device_map="auto", trust_remote_code=True, low_cpu_mem_usage=True, ) print("Loading LoRA adapter...") model = PeftModel.from_pretrained(base_model, ADAPTER_PATH, is_trainable=False) model.eval() if torch.cuda.is_available(): print(f"VRAM loaded: {torch.cuda.memory_allocated()/1e9:.2f} GB / {torch.cuda.get_device_properties(0).total_memory/1e9:.2f} GB") print("✅ Model + adapter ready") def build_prompt(messages): try: return tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True, ) except Exception: text = "" for m in messages: text += f"<{m['role']}>\n{m['content']}\n\n" text += "\n" return text def ask(prompt, history=None): if history is None: history = [{"role": "system", "content": SYSTEM_PROMPT}] messages = history + [{"role": "user", "content": prompt}] full_prompt = build_prompt(messages) inputs = tokenizer(full_prompt, return_tensors="pt").to(model.device) with torch.no_grad(): output = model.generate( **inputs, max_new_tokens=MAX_NEW_TOKENS, do_sample=True, temperature=TEMPERATURE, top_p=TOP_P, pad_token_id=tokenizer.pad_token_id, eos_token_id=tokenizer.eos_token_id, ) new_tokens = output[0][inputs["input_ids"].shape[1]:] reply = tokenizer.decode(new_tokens, skip_special_tokens=True).strip() return reply # Single test prompt reply = ask("Explain how parameterized queries prevent SQL injection with a safe Python example.") print("Assistant:\n", reply) ``` --- ## Optional interactive chat loop Run this after the cell above: ```python history = [{"role": "system", "content": SYSTEM_PROMPT}] while True: user = input("You: ").strip() if user.lower() in {"exit", "quit", "q"}: break if not user: continue reply = ask(user, history) print("Assistant:", reply, "\n") history.append({"role": "user", "content": user}) history.append({"role": "assistant", "content": reply}) ```