from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfigfrom peft import PeftModelimport torch MODEL_ID = "google/gemma-3-4b-it"ADAPTER_ID = "wooyeolj/gemma-3-4b-airecommender" bnb_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_quant_type="nf4", bnb_4bit_use_double_quant=True, bnb_4bit_compute_dtype=torch.bfloat16,) # 1. 베이스 모델 로드base_model = AutoModelForCausalLM.from_pretrained( MODEL_ID, quantization_config=bnb_config, device_map="auto", torch_dtype=torch.bfloat16,)tokenizer = AutoTokenizer.from_pretrained(MODEL_ID) # 2. HuggingFace Hub에서 어댑터 로드model = PeftModel.from_pretrained(base_model, ADAPTER_ID) # 3. 추론SYSTEM_PROMPT = ( "당신은 AI 도구 전문 추천 어시스턴트입니다.\n" "사용자의 질문의 목적을 LLM 모델 추천, AI 에이전트 프레임워크 추천, AI 도구 선택과 무관한 일반적인 질문으로 구분하고,\n" "질문의 목적에 맞게 명확하게 답변합니다.") def generate_response(question, max_new_tokens=250): prompt = ( f"<start_of_turn>user\n" f"{SYSTEM_PROMPT}\n\n{question}" f"<end_of_turn>\n" f"<start_of_turn>model\n" ) inputs = tokenizer(prompt, return_tensors="pt", truncation=True, max_length=512).to(model.device) with torch.no_grad(): outputs = model.generate( **inputs, max_new_tokens=max_new_tokens, do_sample=False, repetition_penalty=1.2, pad_token_id=tokenizer.eos_token_id, eos_token_id=tokenizer.eos_token_id, ) generated = outputs[0][inputs["input_ids"].shape[-1]:] return tokenizer.decode(generated, skip_special_tokens=True).strip() print(generate_response("그림 잘 그리는 무료 AI 모델 추천해줘"))