Spaces:
Paused
Paused
Download model_loader.py from iatechaways/mail_bot: direct link, hf CLI and curl.
- Browser
- Download file 3.8 kB
-
https://huggingface.co/spaces/iatechaways/mail_bot/resolve/main/model_loader.py
- Command line
-
hf download hf://spaces/iatechaways/mail_bot/model_loader.py
-
curl -L -o model_loader.py https://huggingface.co/spaces/iatechaways/mail_bot/resolve/main/model_loader.py
3.8 kB
| # model_loader.py | |
| import os | |
| import torch | |
| import gc | |
| import json | |
| from huggingface_hub import login | |
| from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline | |
| from peft import PeftModel | |
| # CONFIG - change these if your repo name differs | |
| BASE_MODEL = "meta-llama/Llama-3.2-3B" # or local path if you prefer | |
| ADAPTER = "iatechaways/crm_model" # your LoRA adapter on HF | |
| # Get HF token from environment | |
| HF_TOKEN = os.getenv("HF_TOKEN") | |
| # NOTE: For ZeroGPU we LOAD on CPU and move to GPU only during inference. | |
| def load_model_cpu(): | |
| """ | |
| Load base model + adapter into CPU memory (device_map='cpu' or low mem). | |
| Return a dict that holds references to model and tokenizer. | |
| """ | |
| # load tokenizer | |
| tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL, use_fast=True, token=HF_TOKEN) | |
| if tokenizer.pad_token is None: | |
| tokenizer.pad_token = tokenizer.eos_token | |
| tokenizer.padding_side = "right" | |
| # load base model on CPU to minimize early GPU allocation | |
| base = AutoModelForCausalLM.from_pretrained( | |
| BASE_MODEL, | |
| device_map={"": "cpu"}, | |
| torch_dtype=torch.float32, | |
| low_cpu_mem_usage=True, | |
| token=HF_TOKEN | |
| ) | |
| model = PeftModel.from_pretrained( | |
| base, | |
| ADAPTER, | |
| device_map={"": "cpu"}, | |
| torch_dtype=torch.float32, | |
| is_trainable=False, | |
| low_cpu_mem_usage=True, | |
| token=HF_TOKEN | |
| ) | |
| # don't create pipeline here; we'll call generate with model directly | |
| return { | |
| "tokenizer": tokenizer, | |
| "model": model, | |
| "base_name": BASE_MODEL, | |
| "adapter": ADAPTER | |
| } | |
| def move_model_to_gpu(info: dict): | |
| """Move model to GPU and set dtype to float16 for inference speed.""" | |
| if not torch.cuda.is_available(): | |
| return | |
| model = info["model"] | |
| # move to cuda | |
| model.to("cuda") | |
| # if tokenizer/pipeline required, we keep tokenizer on CPU | |
| torch.cuda.empty_cache() | |
| def move_model_to_cpu(info: dict): | |
| """Move model back to CPU & free GPU memory.""" | |
| if not torch.cuda.is_available(): | |
| return | |
| model = info["model"] | |
| model.to("cpu") | |
| torch.cuda.empty_cache() | |
| gc.collect() | |
| def generate_with_model(info: dict, email_text: str, mail_type: str, client_data: dict, max_new_tokens: int = 200): | |
| """Run text generation using the loaded model (assumes model on device).""" | |
| tokenizer = info["tokenizer"] | |
| model = info["model"] | |
| device = next(model.parameters()).device | |
| # Prepare client context | |
| client_context = ( | |
| f"Client Info:\n" | |
| f"Name: {client_data.get('name')}\n" | |
| f"Policy No: {client_data.get('policy_number')}\n" | |
| f"Plan: {client_data.get('indiafirst_life_insurance_plan')}\n" | |
| f"Status: {client_data.get('status')}\n" | |
| f"Premium: ₹{client_data.get('premium_amt')}\n" | |
| f"Due Date: {client_data.get('premium_due_date')}\n\n" | |
| ) | |
| prompt = f"""Email Category: {mail_type} | |
| ### Instruction: | |
| You are an LIC customer-service assistant. Respond politely and concisely (2–5 sentences). | |
| Do NOT invent facts that are not present in the client data. If data is missing, ask the customer to provide correct details. | |
| {client_context} | |
| ### Input: | |
| {email_text} | |
| ### Response: | |
| """ | |
| inputs = tokenizer(prompt, return_tensors="pt", truncation=True, max_length=1024).to(device) | |
| with torch.no_grad(): | |
| outputs = model.generate( | |
| **inputs, | |
| max_new_tokens=max_new_tokens, | |
| temperature=0.6, | |
| top_p=0.9, | |
| do_sample=True, | |
| pad_token_id=tokenizer.eos_token_id, | |
| repetition_penalty=1.12, | |
| num_beams=1 | |
| ) | |
| decoded = tokenizer.decode(outputs[0], skip_special_tokens=True) | |
| return decoded | |