niofrequency commited on
Commit
5af9786
·
verified ·
1 Parent(s): 4f436e7

Create handler.py

Browse files
Files changed (1) hide show
  1. handler.py +81 -0
handler.py ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import base64
3
+ import io
4
+ from PIL import Image
5
+ from diffusers import StableDiffusionXLImg2ImgPipeline
6
+ import os
7
+
8
+ class EndpointHandler():
9
+ def __init__(self, path=""):
10
+ # 'path' is the folder where HF automatically loaded your repo files
11
+ print("Loading ARX Pipeline...")
12
+
13
+ # 1. Point directly to the model you uploaded to the repo
14
+ model_path = os.path.join(path, "biglust.safetensors")
15
+
16
+ # 2. Load the pipeline
17
+ self.pipe = StableDiffusionXLImg2ImgPipeline.from_single_file(
18
+ model_path,
19
+ torch_dtype=torch.float16,
20
+ use_safetensors=True,
21
+ safety_checker=None
22
+ )
23
+
24
+ # 3. Load IP-Adapter (HF will download this from the public hub automatically)
25
+ self.pipe.load_ip_adapter(
26
+ "h94/IP-Adapter",
27
+ subfolder="sdxl_models",
28
+ weight_name="ip-adapter_sdxl.bin"
29
+ )
30
+
31
+ self.pipe.to("cuda")
32
+ print("ARX Pipeline Ready.")
33
+
34
+ def decode_base64_image(self, image_string):
35
+ if "," in image_string:
36
+ image_string = image_string.split(",")[1]
37
+ image_bytes = base64.b64decode(image_string)
38
+ return Image.open(io.BytesIO(image_bytes)).convert("RGB")
39
+
40
+ def encode_image_base64(self, image):
41
+ buffered = io.BytesIO()
42
+ image.save(buffered, format="PNG")
43
+ return base64.b64encode(buffered.getvalue()).decode('utf-8')
44
+
45
+ def __call__(self, data):
46
+ """
47
+ data param format: {"inputs": { "prompt": "...", "init_image": "..." }}
48
+ """
49
+ # HF wraps payloads in an "inputs" key automatically
50
+ inputs = data.pop("inputs", data)
51
+
52
+ prompt = inputs.get("prompt", "masterpiece, best quality")
53
+ negative_prompt = inputs.get("negative_prompt", "lowres, bad anatomy, worst quality, ugly")
54
+ strength = float(inputs.get("strength", 0.65))
55
+ guidance_scale = float(inputs.get("guidance_scale", 7.0))
56
+ num_inference_steps = int(inputs.get("steps", 25))
57
+ ip_adapter_scale = float(inputs.get("ip_adapter_scale", 0.50))
58
+
59
+ init_image_b64 = inputs.get("init_image")
60
+ ip_adapter_image_b64 = inputs.get("ip_adapter_image")
61
+
62
+ if not init_image_b64 or not ip_adapter_image_b64:
63
+ return {"error": "Both init_image and ip_adapter_image must be provided."}
64
+
65
+ init_image = self.decode_base64_image(init_image_b64).resize((1024, 1024))
66
+ ip_image = self.decode_base64_image(ip_adapter_image_b64).resize((1024, 1024))
67
+
68
+ self.pipe.set_ip_adapter_scale(ip_adapter_scale)
69
+
70
+ # Generate!
71
+ result = self.pipe(
72
+ prompt=prompt,
73
+ negative_prompt=negative_prompt,
74
+ image=init_image,
75
+ ip_adapter_image=ip_image,
76
+ strength=strength,
77
+ guidance_scale=guidance_scale,
78
+ num_inference_steps=num_inference_steps
79
+ ).images[0]
80
+
81
+ return {"image": self.encode_image_base64(result)}