Skip to main content

Restyle Room Photos with ControlNet

In this example, we will demonstrate how to use fal-serverless for deploying a ControlNet model.

1. Create a new file called

from __future__ import annotations
from fal_serverless import isolated, cached

from pathlib import Path
import base64
import io

requirements = [

def get_image_from_url_as_bytes(url: str) -> bytes:
import requests

response = requests.get(url)
# This will raise an exception if the request returned an HTTP error code
return response.content

def read_image_bytes(file_path):
with open(file_path, "rb") as file:
image_bytes =
return image_bytes

def load_model():
import torch
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel

controlnet = ControlNetModel.from_pretrained(
"lllyasviel/sd-controlnet-canny", torch_dtype=torch.float16
pipe = StableDiffusionControlNetPipeline.from_pretrained(
"peterwilli/deliberate-2", controlnet=controlnet, torch_dtype=torch.float16

pipe ="cuda:0")
return pipe

def resize_image(input_image, resolution):
import cv2
import numpy as np

H, W, C = input_image.shape
H = float(H)
W = float(W)
k = float(resolution) / min(H, W)
H *= k
W *= k
H = int(np.round(H / 64.0)) * 64
W = int(np.round(W / 64.0)) * 64
img = cv2.resize(
(W, H),
interpolation=cv2.INTER_LANCZOS4 if k > 1 else cv2.INTER_AREA,
return img

def generate(
image_url: str, prompt: str, num_samples: int, num_steps: int, gcs=False
) -> list[bytes] | None:

from controlnet_aux import CannyDetector
from PIL import Image
import numpy as np
import uuid
import os
from base64 import b64encode

image_bytes = get_image_from_url_as_bytes(image_url)

pipe = load_model()
image =

canny = CannyDetector()
init_image = image.convert("RGB")

init_image = resize_image(np.asarray(init_image), 512)
detected_map = canny(init_image, 100, 200)
image = Image.fromarray(detected_map)

negative_prompt = "longbody, lowres, bad anatomy, bad hands, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality"
results = pipe(

result_id = uuid.uuid4()
out_dir = Path(f"/data/cn-results/{result_id}")
out_dir.mkdir(parents=True, exist_ok=True)

for i, res in enumerate(results): / f"res_{i}.png")

file_names = [
f for f in os.listdir(out_dir) if os.path.isfile(os.path.join(out_dir, f))

list_of_bytes = [read_image_bytes(out_dir / f) for f in file_names]
raw_image = list_of_bytes[0]

return b64encode(raw_image).decode("utf-8")

2. Deploy the model as an endpoint

To use this fal-serverless function as an API, you can serve it with the fal-serverless CLI command:

fal-serverless fn serve generate --alias controlnet --auth public

This will return a URL like:

Registered a new revision for function 'controltest' (revision='c75db134-23f0-4863-94cd-3358d6c8d94c').

3. Test it out

curl -H 'content-type: application/json' -H 'accept: application/json' -d '{"image_url":"","prompt":"scandinavian kitchen","num_samples":1,"num_steps":30}'

This should return a JSON with the image encoded in base64.