Skip to content

Commit c4988ea

Browse files
authored
Merge pull request #125 from intel/update-branch
352 user story text to image generation microservice with flux1 schnell and flux1 dev (#356)
2 parents 153c60d + 50af774 commit c4988ea

File tree

16 files changed

+1140
-2
lines changed

16 files changed

+1140
-2
lines changed

usecases/ai/microservices/text-to-image/Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ FROM debian:12-slim
55
ARG DEBIAN_FRONTEND=noninteractive
66

77
# Define the default allowed models and the default model
8-
ARG ALLOWED_MODELS="stable-diffusion-v3 stable-diffusion-v3.5 stable-diffusion-xl"
9-
ARG DEFAULT_MODEL="stable-diffusion-xl"
8+
ARG ALLOWED_MODELS="stable-diffusion-v3.5 stable-diffusion-xl"
9+
ARG DEFAULT_MODEL="stable-diffusion-v3.5"
1010

1111
# Set default model as a build argument and runtime environment variable
1212
ENV DEFAULT_MODEL=${DEFAULT_MODEL}

usecases/ai/microservices/text-to-image/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ It provides endpoints for managing the pipeline, checking the pipeline status, r
88
* Stable Diffusion XL
99
* Stable Diffusion v3.5
1010
* Stable Diffusion v3
11+
* Flux.1 Schnell
12+
* Flux.1 Dev
1113

1214
### Supported Inference Device
1315
* CPU
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.venv
2+
flux-dev
3+
kernel.errors.txt
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# Copyright (C) 2025 Intel Corporation
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
import time
5+
import requests
6+
7+
8+
class PipelineClient:
9+
def __init__(self, base_url="http://localhost:8100"):
10+
"""
11+
Initialize the PipelineClient with the base URL.
12+
:param base_url: The base URL for the API.
13+
"""
14+
self.base_url = base_url
15+
16+
def make_request(self, method, endpoint, data=None, timeout=100):
17+
"""
18+
Make a request to the API.
19+
:param method: HTTP method (GET, POST, etc.).
20+
:param endpoint: API endpoint.
21+
:param data: JSON payload for the request.
22+
:param timeout: Timeout in seconds.
23+
:return: Response object or None on failure.
24+
"""
25+
url = f"{self.base_url}{endpoint}"
26+
try:
27+
response = requests.request(method, url, json=data, timeout=timeout)
28+
response.raise_for_status()
29+
return response
30+
except requests.RequestException as e:
31+
print(f"Error while accessing {url}: {e}")
32+
return None
33+
34+
@staticmethod
35+
def save_image(content, filename):
36+
"""
37+
Save the content as an image file.
38+
:param content: Binary content of the image.
39+
:param filename: Filename to save the image.
40+
"""
41+
try:
42+
with open(filename, "wb") as file:
43+
file.write(content)
44+
print(f"Image saved as {filename}")
45+
except IOError as e:
46+
print(f"Failed to save image: {e}")
47+
48+
def wait_for_completion(self, timeout=60, poll_interval=2):
49+
"""
50+
Wait for the pipeline to complete.
51+
:param timeout: Maximum time to wait in seconds.
52+
:param poll_interval: Time between status checks.
53+
:return: True if completed, False otherwise.
54+
"""
55+
start_time = time.time()
56+
while time.time() - start_time < timeout:
57+
response = self.make_request("GET", "/pipeline/status", timeout=10)
58+
if response:
59+
status = response.json()
60+
print(f"Pipeline status: Running={status['running']}, Completed={status['completed']}")
61+
if status["completed"]:
62+
return True
63+
time.sleep(poll_interval)
64+
print("Timeout reached. Pipeline execution did not complete.")
65+
return False
66+
67+
def check_health(self):
68+
"""
69+
Check the health of the API.
70+
:return: True if the health check passes, False otherwise.
71+
"""
72+
response = self.make_request("GET", "/health")
73+
if response:
74+
health_status = response.json()
75+
print(f"Health status: {health_status['status']}")
76+
return health_status['status'] == "healthy"
77+
else:
78+
print("Failed to perform health check.")
79+
return False
80+
81+
82+
def main():
83+
client = PipelineClient()
84+
85+
# Step 1: Health check
86+
if not client.check_health():
87+
print("Health check failed. Exiting.")
88+
return
89+
90+
# Step 2: Select the device
91+
response = client.make_request("POST", "/pipeline/select-device", {"device": "GPU"})
92+
if response:
93+
print(response.json())
94+
95+
# Step 3: Trigger the pipeline with additional parameters
96+
response = client.make_request(
97+
"POST",
98+
"/pipeline/run",
99+
{
100+
"prompt": "A raccoon trapped inside a glass jar full of colorful candies, the background is steamy with vivid colors",
101+
"width": 512, # Additional parameter: width
102+
"height": 512, # Additional parameter: height
103+
"num_inference_steps": 5 # Additional parameter: num_inference_steps
104+
},
105+
)
106+
if not response:
107+
print("Failed to trigger the pipeline.")
108+
return
109+
print(response.json())
110+
111+
# Step 4: Wait for completion
112+
if not client.wait_for_completion():
113+
return
114+
115+
# Step 5: Retrieve the generated image
116+
response = client.make_request("GET", "/pipeline/image")
117+
if response:
118+
client.save_image(response.content, "output_image.png")
119+
else:
120+
print("Failed to retrieve the generated image.")
121+
122+
123+
if __name__ == "__main__":
124+
main()
125+
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Copyright (C) 2025 Intel Corporation
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
import subprocess # nosec - disable B404:import-subprocess check
5+
import sys
6+
from pathlib import Path
7+
from typing import Dict
8+
import platform
9+
10+
11+
def clone_repo(repo_url: str, revision: str = None, add_to_sys_path: bool = True) -> Path:
12+
repo_path = Path(repo_url.split("/")[-1].replace(".git", ""))
13+
14+
if not repo_path.exists():
15+
try:
16+
subprocess.run(["git", "clone", repo_url], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
17+
except Exception as exc:
18+
print(f"Failed to clone the repository: {exc.stderr}")
19+
raise
20+
21+
if revision:
22+
subprocess.Popen(["git", "checkout", revision], cwd=str(repo_path))
23+
if add_to_sys_path and str(repo_path.resolve()) not in sys.path:
24+
sys.path.insert(0, str(repo_path.resolve()))
25+
26+
return repo_path
27+
28+
29+
def optimum_cli(model_id, output_dir, show_command=True, additional_args: Dict[str, str] = None):
30+
export_command = f"optimum-cli export openvino --model {model_id} {output_dir}"
31+
if additional_args is not None:
32+
for arg, value in additional_args.items():
33+
export_command += f" --{arg}"
34+
if value:
35+
export_command += f" {value}"
36+
37+
if show_command:
38+
from IPython.display import Markdown, display
39+
40+
display(Markdown("**Export command:**"))
41+
display(Markdown(f"`{export_command}`"))
42+
43+
subprocess.run(export_command.split(" "), shell=(platform.system() == "Windows"), check=True)

0 commit comments

Comments
 (0)