emerald-rag / model.py
ben-wang's picture
Update model.py
861540a verified
Raw
History Blame Contribute Delete
2.73 kB
"""
model.py - Inference & Model Orchestration Layer
This module encapsulates the logic for loading and executing high-parameter LLMs.
It manages the transition from raw user input to structured data by coordinating
the chat model, embedding model, and Pydantic-based output validation.
"""
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_core.output_parsers import PydanticOutputParser
from schema import PokemonEmeraldResponse
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
CHAT_MODEL_ID = "mistralai/Mistral-Small-Instruct-2409"
EMBEDDING_MODEL_ID = "nomic-ai/nomic-embed-text-v1.5"
def load_chat_model():
"""
Bootstrap the tokenizer and chat model for the RAG pipeline.
Returns: (model, tokenizer) tuple.
"""
print(f"Loading {CHAT_MODEL_ID} model...")
tokenizer = AutoTokenizer.from_pretrained(CHAT_MODEL_ID)
model = AutoModelForCausalLM.from_pretrained(
CHAT_MODEL_ID,
torch_dtype="auto",
device_map="auto"
)
print("Model loaded!")
return model, tokenizer
def load_embedding_model():
"""
Bootstrap the HuggingFaceEmbeddings model for the RAG pipeline.
Returns: An instance of HuggingFaceEmbeddings configured with EMBEDDING_MODEL_ID.
"""
print(f"Loading {EMBEDDING_MODEL_ID} model...")
embedding_model = HuggingFaceEmbeddings(model_name=EMBEDDING_MODEL_ID)
print("Model loaded!")
return embedding_model
def generate_answer(chat_model, tokenizer, prompt, max_retries=3):
"""
Executes the core RAG generation loop with automated schema validation.
This function manages the transition from raw model output to structured JSON.
It includes a retry mechanism to handle edge-case parsing failures, ensuring
the final response adheres to the PokemonEmeraldResponse Pydantic schema.
"""
print("Generating chat response...")
inputs = tokenizer(prompt, return_tensors="pt").to("cuda")
inputs_size = len(inputs.input_ids[0])
parser = PydanticOutputParser(pydantic_object=PokemonEmeraldResponse)
attempt = 0
while attempt < max_retries:
try:
response = chat_model.generate(
**inputs,
max_new_tokens=256,
num_beams=3,
early_stopping=True,
repetition_penalty=1.2,
length_penalty=1,
)
output = tokenizer.decode(response[0][inputs_size:], skip_special_tokens=True)
return parser.parse(output)
except Exception as e:
print(f"Chat model response generation failed, attempt {attempt}.")
attempt += 1
print(f"Parsing failed. Output: {output}")