chore: fix metadata propertoes for HF Inference Endpoint
Browse files- README.md +61 -2
- api-inference/config.json +5 -0
- model-index.json +18 -0
- test_endpoint.py +134 -0
README.md
CHANGED
|
@@ -7,6 +7,7 @@ tags:
|
|
| 7 |
- text-to-image
|
| 8 |
- diffusers
|
| 9 |
- huggingface-inference-endpoints
|
|
|
|
| 10 |
pipeline_tag: text-to-image
|
| 11 |
inference: true
|
| 12 |
---
|
|
@@ -129,10 +130,20 @@ Response format from the local server:
|
|
| 129 |
3. Click "Create a new endpoint"
|
| 130 |
4. Configure your endpoint with the following settings:
|
| 131 |
- Name: Give your endpoint a name
|
|
|
|
| 132 |
- Instance Type: Choose a GPU instance (recommended: at least 16GB VRAM for SDXL)
|
| 133 |
- Replicas: Start with 1 replica
|
| 134 |
- Autoscaling: Configure as needed
|
| 135 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 136 |
|
| 137 |
The Hugging Face Inference Endpoints service will automatically detect and use your `EndpointHandler` class in the `handler.py` file.
|
| 138 |
|
|
@@ -203,4 +214,52 @@ The local server uses the FastAPI implementation included in `handler.py` that p
|
|
| 203 |
|
| 204 |
## License
|
| 205 |
|
| 206 |
-
This project is licensed under the terms of the MIT license.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
- text-to-image
|
| 8 |
- diffusers
|
| 9 |
- huggingface-inference-endpoints
|
| 10 |
+
- custom-inference
|
| 11 |
pipeline_tag: text-to-image
|
| 12 |
inference: true
|
| 13 |
---
|
|
|
|
| 130 |
3. Click "Create a new endpoint"
|
| 131 |
4. Configure your endpoint with the following settings:
|
| 132 |
- Name: Give your endpoint a name
|
| 133 |
+
- Region: Choose a region close to your users (e.g., us-east-1)
|
| 134 |
- Instance Type: Choose a GPU instance (recommended: at least 16GB VRAM for SDXL)
|
| 135 |
- Replicas: Start with 1 replica
|
| 136 |
- Autoscaling: Configure as needed
|
| 137 |
+
|
| 138 |
+
**IMPORTANT: IF YOU SEE THIS WARNING**:
|
| 139 |
+
> "Warning: deploying this model will probably fail because the model's Diffusers pipeline is not set"
|
| 140 |
+
|
| 141 |
+
5. Click "Continue anyway" - this is expected because you're using a custom handler implementation
|
| 142 |
+
6. Under Advanced configuration:
|
| 143 |
+
- Make sure "Framework" is set to "Custom"
|
| 144 |
+
- Configure "Task" as "Text-to-Image"
|
| 145 |
+
|
| 146 |
+
7. Click "Create endpoint"
|
| 147 |
|
| 148 |
The Hugging Face Inference Endpoints service will automatically detect and use your `EndpointHandler` class in the `handler.py` file.
|
| 149 |
|
|
|
|
| 214 |
|
| 215 |
## License
|
| 216 |
|
| 217 |
+
This project is licensed under the terms of the MIT license.
|
| 218 |
+
|
| 219 |
+
## Testing Your Inference Endpoint
|
| 220 |
+
|
| 221 |
+
We've included a test script `test_endpoint.py` to help you test your deployed endpoint.
|
| 222 |
+
|
| 223 |
+
### Prerequisites
|
| 224 |
+
- Python 3.7+
|
| 225 |
+
- Your Hugging Face API token
|
| 226 |
+
- An active Hugging Face Inference Endpoint
|
| 227 |
+
|
| 228 |
+
### Installation
|
| 229 |
+
```bash
|
| 230 |
+
pip install requests pillow
|
| 231 |
+
```
|
| 232 |
+
|
| 233 |
+
### Usage
|
| 234 |
+
```bash
|
| 235 |
+
python test_endpoint.py --token "YOUR_HF_API_TOKEN" --url "YOUR_ENDPOINT_URL" --prompt "your test prompt here"
|
| 236 |
+
```
|
| 237 |
+
|
| 238 |
+
#### Additional Options
|
| 239 |
+
```
|
| 240 |
+
--negative_prompt TEXT Negative prompt to guide generation
|
| 241 |
+
--seed INTEGER Random seed for reproducibility
|
| 242 |
+
--steps INTEGER Number of inference steps (default: 30)
|
| 243 |
+
--guidance FLOAT Guidance scale (default: 7.0)
|
| 244 |
+
--width INTEGER Image width (default: 1024)
|
| 245 |
+
--height INTEGER Image height (default: 768)
|
| 246 |
+
--output_dir TEXT Directory to save generated images (default: "generated_images")
|
| 247 |
+
```
|
| 248 |
+
|
| 249 |
+
#### Example
|
| 250 |
+
```bash
|
| 251 |
+
python test_endpoint.py \
|
| 252 |
+
--token "hf_..." \
|
| 253 |
+
--url "https://api-inference.huggingface.co/models/username/your-repo-name" \
|
| 254 |
+
--prompt "beautiful sunset over mountains" \
|
| 255 |
+
--negative_prompt "blurry, low quality" \
|
| 256 |
+
--seed 42 \
|
| 257 |
+
--steps 30 \
|
| 258 |
+
--guidance 7.5
|
| 259 |
+
```
|
| 260 |
+
|
| 261 |
+
This will:
|
| 262 |
+
1. Send a request to your endpoint
|
| 263 |
+
2. Download the generated image
|
| 264 |
+
3. Save it to the specified output directory
|
| 265 |
+
4. Display the seed used for generation
|
api-inference/config.json
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"framework": "custom",
|
| 3 |
+
"task": "text-to-image",
|
| 4 |
+
"custom_handler": "handler:EndpointHandler"
|
| 5 |
+
}
|
model-index.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"_class_name": "CustomInferenceAPI",
|
| 3 |
+
"task": "text-to-image",
|
| 4 |
+
"widget": {
|
| 5 |
+
"input_template": {
|
| 6 |
+
"inputs": "beautiful landscape with mountains",
|
| 7 |
+
"parameters": {
|
| 8 |
+
"negative_prompt": "blurry, low quality",
|
| 9 |
+
"seed": 42,
|
| 10 |
+
"inference_steps": 30,
|
| 11 |
+
"guidance_scale": 7,
|
| 12 |
+
"width": 1024,
|
| 13 |
+
"height": 768
|
| 14 |
+
}
|
| 15 |
+
},
|
| 16 |
+
"output_widget": "Base64ImageOutput"
|
| 17 |
+
}
|
| 18 |
+
}
|
test_endpoint.py
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
# This script demonstrates how to test your Hugging Face Inference Endpoint
|
| 3 |
+
# Replace the API_TOKEN and API_URL with your actual values
|
| 4 |
+
|
| 5 |
+
import requests
|
| 6 |
+
import json
|
| 7 |
+
import base64
|
| 8 |
+
from PIL import Image
|
| 9 |
+
import io
|
| 10 |
+
import argparse
|
| 11 |
+
import os
|
| 12 |
+
|
| 13 |
+
def test_inference_endpoint(api_token, api_url, prompt, negative_prompt=None,
|
| 14 |
+
seed=None, inference_steps=30, guidance_scale=7,
|
| 15 |
+
width=1024, height=768, output_dir="generated_images"):
|
| 16 |
+
"""
|
| 17 |
+
Test a Hugging Face Inference Endpoint for image generation.
|
| 18 |
+
|
| 19 |
+
Args:
|
| 20 |
+
api_token (str): Your Hugging Face API token
|
| 21 |
+
api_url (str): The URL of your inference endpoint
|
| 22 |
+
prompt (str): The text prompt for image generation
|
| 23 |
+
negative_prompt (str, optional): Negative prompt to guide generation
|
| 24 |
+
seed (int, optional): Random seed for reproducibility
|
| 25 |
+
inference_steps (int): Number of inference steps
|
| 26 |
+
guidance_scale (float): Guidance scale for generation
|
| 27 |
+
width (int): Image width
|
| 28 |
+
height (int): Image height
|
| 29 |
+
output_dir (str): Directory to save generated images
|
| 30 |
+
"""
|
| 31 |
+
# Create output directory if it doesn't exist
|
| 32 |
+
os.makedirs(output_dir, exist_ok=True)
|
| 33 |
+
|
| 34 |
+
# Headers for the request
|
| 35 |
+
headers = {
|
| 36 |
+
"Authorization": f"Bearer {api_token}",
|
| 37 |
+
"Content-Type": "application/json"
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
# Build parameters dictionary with provided values
|
| 41 |
+
parameters = {
|
| 42 |
+
"width": width,
|
| 43 |
+
"height": height,
|
| 44 |
+
"inference_steps": inference_steps,
|
| 45 |
+
"guidance_scale": guidance_scale
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
# Add optional parameters if provided
|
| 49 |
+
if negative_prompt:
|
| 50 |
+
parameters["negative_prompt"] = negative_prompt
|
| 51 |
+
if seed:
|
| 52 |
+
parameters["seed"] = seed
|
| 53 |
+
|
| 54 |
+
# Request payload
|
| 55 |
+
payload = {
|
| 56 |
+
"inputs": prompt,
|
| 57 |
+
"parameters": parameters
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
print(f"Sending request to {api_url}...")
|
| 61 |
+
print(f"Prompt: '{prompt}'")
|
| 62 |
+
|
| 63 |
+
try:
|
| 64 |
+
# Send the request
|
| 65 |
+
response = requests.post(api_url, headers=headers, json=payload)
|
| 66 |
+
|
| 67 |
+
# Check for errors
|
| 68 |
+
if response.status_code != 200:
|
| 69 |
+
print(f"Error: {response.status_code} - {response.text}")
|
| 70 |
+
return
|
| 71 |
+
|
| 72 |
+
# Parse the response
|
| 73 |
+
result = response.json()
|
| 74 |
+
|
| 75 |
+
# Check for error in the response
|
| 76 |
+
if isinstance(result, dict) and "error" in result:
|
| 77 |
+
print(f"API Error: {result['error']}")
|
| 78 |
+
return
|
| 79 |
+
|
| 80 |
+
# Extract the generated image and seed
|
| 81 |
+
if isinstance(result, list) and len(result) > 0:
|
| 82 |
+
item = result[0]
|
| 83 |
+
if "generated_image" in item:
|
| 84 |
+
# Convert the base64-encoded image to a PIL Image
|
| 85 |
+
image_bytes = base64.b64decode(item["generated_image"])
|
| 86 |
+
image = Image.open(io.BytesIO(image_bytes))
|
| 87 |
+
|
| 88 |
+
# Create a filename based on the prompt and seed
|
| 89 |
+
used_seed = item.get("seed", "unknown_seed")
|
| 90 |
+
filename = f"{output_dir}/generated_{used_seed}.png"
|
| 91 |
+
|
| 92 |
+
# Save the image
|
| 93 |
+
image.save(filename)
|
| 94 |
+
print(f"Image saved to {filename}")
|
| 95 |
+
print(f"Seed: {used_seed}")
|
| 96 |
+
|
| 97 |
+
return image
|
| 98 |
+
else:
|
| 99 |
+
print("Response doesn't contain 'generated_image' field")
|
| 100 |
+
else:
|
| 101 |
+
print("Unexpected response format:", result)
|
| 102 |
+
|
| 103 |
+
except Exception as e:
|
| 104 |
+
print(f"Error: {str(e)}")
|
| 105 |
+
|
| 106 |
+
if __name__ == "__main__":
|
| 107 |
+
# Parse command line arguments
|
| 108 |
+
parser = argparse.ArgumentParser(description="Test Hugging Face Inference Endpoints for image generation")
|
| 109 |
+
parser.add_argument("--token", required=True, help="Your Hugging Face API token")
|
| 110 |
+
parser.add_argument("--url", required=True, help="URL of your inference endpoint")
|
| 111 |
+
parser.add_argument("--prompt", required=True, help="Text prompt for image generation")
|
| 112 |
+
parser.add_argument("--negative_prompt", help="Negative prompt")
|
| 113 |
+
parser.add_argument("--seed", type=int, help="Random seed for reproducibility")
|
| 114 |
+
parser.add_argument("--steps", type=int, default=30, help="Number of inference steps")
|
| 115 |
+
parser.add_argument("--guidance", type=float, default=7, help="Guidance scale")
|
| 116 |
+
parser.add_argument("--width", type=int, default=1024, help="Image width")
|
| 117 |
+
parser.add_argument("--height", type=int, default=768, help="Image height")
|
| 118 |
+
parser.add_argument("--output_dir", default="generated_images", help="Directory to save generated images")
|
| 119 |
+
|
| 120 |
+
args = parser.parse_args()
|
| 121 |
+
|
| 122 |
+
# Call the test function with provided arguments
|
| 123 |
+
test_inference_endpoint(
|
| 124 |
+
api_token=args.token,
|
| 125 |
+
api_url=args.url,
|
| 126 |
+
prompt=args.prompt,
|
| 127 |
+
negative_prompt=args.negative_prompt,
|
| 128 |
+
seed=args.seed,
|
| 129 |
+
inference_steps=args.steps,
|
| 130 |
+
guidance_scale=args.guidance,
|
| 131 |
+
width=args.width,
|
| 132 |
+
height=args.height,
|
| 133 |
+
output_dir=args.output_dir
|
| 134 |
+
)
|