Ephraimmm commited on
Commit
91c1aad
·
verified ·
1 Parent(s): eeb37eb

Update handler.py

Browse files
Files changed (1) hide show
  1. handler.py +67 -99
handler.py CHANGED
@@ -1,101 +1,69 @@
1
- from typing import Any, Dict
2
- import torch
3
- from transformers import AutoModelForCausalLM, AutoTokenizer
4
- from peft import PeftModel
5
 
6
- class EndpointHandler:
7
- def __init__(self, path=""):
8
- # CORRECTED: Use gemma-3-4b instead of gemma-2-2b
9
- #unsloth/gemma-3-4b-it-unsloth-bnb-4bit
10
- model_id = "unsloth/gemma-3-4b-it-unsloth"
11
-
12
- self.tokenizer = AutoTokenizer.from_pretrained(model_id)
13
- model = AutoModelForCausalLM.from_pretrained(
14
- model_id,
15
- load_in_4bit=True,
16
- device_map="auto"
17
- )
18
- self.model = PeftModel.from_pretrained(model, path)
19
-
20
- def __call__(self, data: Dict[str, Any]) -> Dict[str, Any]:
21
- # Support OpenAI Chat Completion format
22
- if "messages" in data:
23
- messages = data["messages"]
24
-
25
- # Extract system message if exists
26
- system_msg = next((m["content"] for m in messages
27
- if m["role"] == "system"), None)
28
-
29
- # Extract user message (last user message)
30
- user_msg = next((m["content"] for m in reversed(messages)
31
- if m["role"] == "user"), "")
32
-
33
- # Format prompt with system message if provided
34
- if system_msg:
35
- prompt = f"{system_msg}\n\nUser: {user_msg}\nAssistant:"
36
- else:
37
- prompt = user_msg
38
-
39
- # Support Text Generation format (backward compatible)
40
- else:
41
- prompt = data.get("inputs", "")
42
-
43
- # Extract generation parameters
44
- params = data.get("parameters", {})
45
- max_new_tokens = params.get("max_new_tokens", 128)
46
- temperature = params.get("temperature", 0.7)
47
- top_p = params.get("top_p", 0.9)
48
- do_sample = params.get("do_sample", True)
49
-
50
- # Tokenize input
51
- inputs = self.tokenizer(prompt, return_tensors="pt").to(self.model.device)
52
-
53
- # Generate response
54
- with torch.no_grad():
55
- outputs = self.model.generate(
56
- **inputs,
57
- max_new_tokens=max_new_tokens,
58
- temperature=temperature,
59
- top_p=top_p,
60
- do_sample=do_sample,
61
- pad_token_id=self.tokenizer.pad_token_id,
62
- eos_token_id=self.tokenizer.eos_token_id
63
- )
64
-
65
- # Decode generated text
66
- generated_text = self.tokenizer.decode(
67
- outputs[0],
68
- skip_special_tokens=True
69
- )
70
-
71
- # Remove the input prompt from output
72
- if prompt in generated_text:
73
- generated_text = generated_text.replace(prompt, "").strip()
74
-
75
- # Return in appropriate format based on input type
76
- if "messages" in data:
77
- # OpenAI Chat Completion response format
78
- return {
79
- "id": "chatcmpl-pidgin",
80
- "object": "chat.completion",
81
- "created": int(torch.cuda.Event().record().elapsed_time(torch.cuda.Event())),
82
- "model": "pidgin-gemma-3",
83
- "choices": [{
84
- "index": 0,
85
- "message": {
86
- "role": "assistant",
87
- "content": generated_text
88
- },
89
- "finish_reason": "stop"
90
- }],
91
- "usage": {
92
- "prompt_tokens": len(inputs["input_ids"][0]),
93
- "completion_tokens": len(outputs[0]) - len(inputs["input_ids"][0]),
94
- "total_tokens": len(outputs[0])
95
- }
96
  }
97
- else:
98
- # Text Generation response format
99
- return [{
100
- "generated_text": generated_text
101
- }]
 
1
+ # handler.py
2
+ import json
3
+ from typing import List, Dict, Any
4
+ from transformers import pipeline
5
 
6
+ # ---- LOAD MODEL ON STARTUP ----
7
+ pipe = pipeline(
8
+ "text-generation",
9
+ model="Ephraimmm/PIDGIN_gemma-3",
10
+ device_map="auto"
11
+ )
12
+
13
+
14
+ # ---- UTIL: convert OpenAI-like body into prompt ----
15
+ def build_prompt(messages: List[Dict[str, str]]) -> str:
16
+ out = []
17
+ for m in messages:
18
+ role = m["role"]
19
+ content = m["content"]
20
+ if role == "system":
21
+ out.append(f"<<SYS>> {content}\n")
22
+ elif role == "user":
23
+ out.append(f"User: {content}")
24
+ elif role == "assistant":
25
+ out.append(f"Assistant: {content}")
26
+ out.append("Assistant:")
27
+ return "\n".join(out)
28
+
29
+
30
+ # ---- MAIN HANDLER ENTRYPOINT ----
31
+ def handle(event, context=None):
32
+ """AWS/SageMaker/HF style single entry."""
33
+ if isinstance(event, str): # if raw body
34
+ event = json.loads(event)
35
+
36
+ # Expect OpenAI style body
37
+ messages = event["messages"]
38
+ max_tokens = event.get("max_tokens", 256)
39
+ temperature = event.get("temperature", 0.7)
40
+ top_p = event.get("top_p", 0.95)
41
+
42
+ prompt = build_prompt(messages)
43
+
44
+ out = pipe(
45
+ prompt,
46
+ max_new_tokens=max_tokens,
47
+ do_sample=True,
48
+ temperature=temperature,
49
+ top_p=top_p,
50
+ eos_token_id=pipe.tokenizer.eos_token_id,
51
+ )[0]["generated_text"]
52
+
53
+ # extract only the assistant continuation
54
+ completion = out.replace(prompt, "").strip()
55
+
56
+ # ---- RETURN IN OPENAI CHAT FORMAT ----
57
+ resp = {
58
+ "id": "chatcmpl-local-1",
59
+ "object": "chat.completion",
60
+ "choices": [{
61
+ "index": 0,
62
+ "finish_reason": "stop",
63
+ "message": {
64
+ "role": "assistant",
65
+ "content": completion
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  }
67
+ }],
68
+ }
69
+ return resp