prabalGaur commited on
Commit
57f04b3
·
verified ·
1 Parent(s): bdcbcb8

Upload pricer_service2.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. pricer_service2.py +83 -0
pricer_service2.py ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import modal
2
+ from modal import Volume, Image
3
+ # Setup - define our infrastructure with code!
4
+
5
+ app = modal.App("pricer-service")
6
+ image = Image.debian_slim().pip_install(
7
+ "huggingface", "torch", "transformers", "bitsandbytes", "accelerate", "peft"
8
+ )
9
+
10
+ # This collects the secret from Modal.
11
+ # Depending on your Modal configuration, you may need to replace "huggingface-secret" with "hf-secret"
12
+ secrets = [modal.Secret.from_name("huggingface-secret")]
13
+
14
+ GPU = "T4"
15
+ BASE_MODEL = "meta-llama/Llama-3.2-3B"
16
+ PROJECT_NAME = "price"
17
+ HF_USER = "ed-donner" # your HF name here! Or use mine if you just want to reproduce my results.
18
+ RUN_NAME = "2025-11-28_18.47.07"
19
+ PROJECT_RUN_NAME = f"{PROJECT_NAME}-{RUN_NAME}"
20
+ REVISION = "b19c8bfea3b6ff62237fbb0a8da9779fc12cefbd"
21
+ FINETUNED_MODEL = f"{HF_USER}/{PROJECT_RUN_NAME}"
22
+ CACHE_DIR = "/cache"
23
+
24
+ # Change this to 1 if you want Modal to be always running, otherwise it will go cold after 2 mins
25
+ MIN_CONTAINERS = 0
26
+
27
+ PREFIX = "Price is $"
28
+ QUESTION = "What does this cost to the nearest dollar?"
29
+
30
+ hf_cache_volume = Volume.from_name("hf-hub-cache", create_if_missing=True)
31
+
32
+
33
+ @app.cls(
34
+ image=image.env({"HF_HUB_CACHE": CACHE_DIR}),
35
+ secrets=secrets,
36
+ gpu=GPU,
37
+ timeout=1800,
38
+ min_containers=MIN_CONTAINERS,
39
+ volumes={CACHE_DIR: hf_cache_volume},
40
+ )
41
+ class Pricer:
42
+ @modal.enter()
43
+ def setup(self):
44
+ import torch
45
+ from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
46
+ from peft import PeftModel
47
+
48
+ # Quant Config
49
+ quant_config = BitsAndBytesConfig(
50
+ load_in_4bit=True,
51
+ bnb_4bit_use_double_quant=True,
52
+ bnb_4bit_compute_dtype=torch.float16,
53
+ bnb_4bit_quant_type="nf4",
54
+ )
55
+
56
+ # Load model and tokenizer
57
+ self.tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL)
58
+ self.tokenizer.pad_token = self.tokenizer.eos_token
59
+ self.tokenizer.padding_side = "right"
60
+ self.base_model = AutoModelForCausalLM.from_pretrained(
61
+ BASE_MODEL, quantization_config=quant_config, device_map="auto"
62
+ )
63
+ self.fine_tuned_model = PeftModel.from_pretrained(
64
+ self.base_model, FINETUNED_MODEL, revision=REVISION
65
+ )
66
+
67
+ @modal.method()
68
+ def price(self, description: str) -> float:
69
+ import re
70
+ import torch
71
+ from transformers import set_seed
72
+
73
+ set_seed(42)
74
+ prompt = f"{QUESTION}\n\n{description}\n\n{PREFIX}"
75
+
76
+ inputs = self.tokenizer.encode(prompt, return_tensors="pt").to("cuda")
77
+ with torch.no_grad():
78
+ outputs = self.fine_tuned_model.generate(inputs, max_new_tokens=5)
79
+ result = self.tokenizer.decode(outputs[0])
80
+ contents = result.split("Price is $")[1]
81
+ contents = contents.replace(",", "")
82
+ match = re.search(r"[-+]?\d*\.\d+|\d+", contents)
83
+ return float(match.group()) if match else 0