×
Community Blog Deploy Stable Diffusion API Service in EAS

Deploy Stable Diffusion API Service in EAS

This article describes how to use Elastic Algorithm Service (EAS) of Platform for AI (AI) to deploy the Stable Diffusion (SD) API service and how to use SD APIs for model inference.

Background Information

The SD API deployment uses the same basic image as the one you can use to deploy a web UI application. For more information about the deployment, see Deploy Stable Diffusion for AI image generation with EAS in a few clicks.

You can deploy the SD API service as a synchronous service or an asynchronous service. For more information, see the Deploy a synchronous service and Deploy an asynchronous service sections of this article. You can send synchronous or asynchronous API requests to call the service, and verify the model based on the request results. For more information, see the Call the synchronous service and Call the asynchronous service sections of this article. If you send a synchronous request, the client waits for the returned results of service calls. If you send an asynchronous request, the client no longer waits for the response after sending a request to the server. Instead, the client subscribes to the request so that the server can automatically push the inference result to the client. You can select the mode of model deployment and service invocation based on your business requirements.

In addition, EAS supports additional features based on the native SD webUI interface. You can add optional parameters in addition to the required parameters when you call an API. This way, you can use more features and customize your service. For more information, see Additional parameters of API operations sections of this article.

Prerequisites

• EAS is activated. The default workspace and pay-as-you-go resources are created. For more information, see Activate PAI and create the default workspace.

• A general-purpose NAS file system is created to store model files. For more information, see Create a file system.

• An Object Storage Service (OSS) bucket is created to store generated images. For more information, see Create buckets.

Deploy a Synchronous Service

You can select one of the following methods to deploy the service based on your business requirements. We recommend that you use Method 1 when you deploy the model for the first time.

Method 1: Deploy the Model in the Console

1.  Go to the EAS page.

a) Log on to the PAI console.

b) In the left-side navigation pane, click Workspaces. On the Workspaces page, click the name of the workspace to which the model service that you want to manage belongs.

c) In the left-side navigation pane, choose Model Deployment>Elastic Algorithm Service (EAS) to go to the EAS-Online Model Services page.

1

2.  On the EAS-Online Model Services page, click Deploy Service.

3.  On the Deploy Service page, configure the required parameters. The following table describes key parameters.

Parameter Description
Service Name The name of the service. The name sdapi_demo is used in this example.
Deployment Method Select Deploy Service by Using Image.
Select Image Click PAI Image. Select stable-diffusion-webui from the Image drop-down list and 3.2 from the Image Version drop-down list.
Note: You can select the latest version for the image when you deploy the model service.
Model Settings Click Specify Model Settings to configure the model.
o We recommend that you configure both OSS and Apsara File Storage NAS. The OSS path is used to store the generated images, and the NAS path is used to store the models.
o You can also use either OSS or NAS.
● NAS allows you to switch models and generate images in a faster manner.
● OSS allows you to upload files in an easier manner. However, the model switching and image generation may take longer time than NAS.

The following section describes how to configure OSS and NAS.
o OSS
● Set the OSS path to the path of an OSS bucket that you created.
● Set Mount Path to /code/stable-diffusion-webui/data-oss.
o NAS
NAS Mount Target: Select an existing NAS file system and mount target.
NAS Source Path: /.
Mount Path: /code/stable-diffusion-webui/data-nas.
Command to Run Set the Command to Run to ./webui.sh --listen --port=8000 --skip-version-check --no-hashing --no-download-sd-model --skip-install --api --filebrowser --data-dir data-nas.
Port Number: Set to 8000.
Resource Group Type Select Public Resource Group.
Resource Configuration Mode Select General.
Resource Configuration Select a GPU type. We recommend that you use the ml.gu7i.c16m60.1-gu30 instance type in terms of cost-effectiveness.
VPC The system automatically selects the virtual private cloud (VPC) that the specified NAS file system resides.

4.  Click Deploy. The deployment takes several seconds to complete.

When the Model Status enters Running, the service is deployed.

Method 2: Deploy the Model by Usig JSON

1.  Go to the Deploy Service page described in Method 1.

2.  In the Configuration Editor section, click JSON Deployment. Enter the following code to the editor field.

{
    "metadata": {
        "instance": 1,
        "name": "sd_v32",
    },
    "containers": [
        {
            "image": "eas-registry-vpc.<region>.cr.aliyuncs.com/pai-eas/stable-diffusion-webui:3.2",
            "script": "./webui.sh --listen --port=8000 --skip-version-check --no-hashing --no-download-sd-model --skip-install --api --filebrowser --data-dir data-nas",
            "port": 8000
        }
    ],
    "cloud": {
        "computing": {
            "instance_type": "ml.gu7i.c16m60.1-gu30",
            "instances": null
        },
        "networking": {
            "vpc_id": "vpc-t4nmd6nebhlwwexk2****",
            "vswitch_id": "vsw-t4nfue2s10q2i0ae3****",
            "security_group_id": "sg-t4n85ksesuiq3wez****"
        }
    },
    "storage": [
        {
            "oss": {
                "path": "oss://examplebucket/data-oss",
                "readOnly": false
            },
            "properties": {
                "resource_type": "model"
            },
            "mount_path": "/code/stable-diffusion-webui/data-oss"
        },
        {
            "nfs": {
                "path": "/",
                "server": "726434****-aws0.ap-southeast-1.nas.aliyuncs.com"
            },
            "properties": {
                "resource_type": "model"
            },
            "mount_path": "/code/stable-diffusion-webui/data-nas"
        }
    ]
} 

Parameters:

o metadata.name: The name of the custom model service.

o containers.image: Replace <region> with the actual region ID. For more information about how to obtain the region ID, see Regions and zones.

o cloud.networking: Configure the VPC, including the VPC ID (vpc_id), vSwitch ID (vswitch_id), and the security group ID (security_group_id). The VPC must be the same as that of the general-purpose NAS file system.

o storage.oss.path: Set the value to the path of an existing OSS bucket.

o storage.nfs.server: Set the value to an existing NAS file system.

3.  Click Deploy. The deployment takes several seconds to complete.

When the Model Status enters Running, the service is deployed.

Call the Synchronous Service

After the synchronous service is deployed, you can perform the following steps to send a synchronous request.

1.  Obtain the invocation information.

After the service is deployed, click Invocation Method in the Service Type column. In the Invocation Method dialog box, click the Public Endpoint tab to view the endpoint and token of the service.

2

2.  Use one of the following methods to send a synchronous request.

Use a cURL Command to Send a Service Request

Sample code:

curl --location --request POST '<service_url>/sdapi/v1/txt2img' \
--header 'Authorization: <token>' \
--header 'Content-Type: application/json' \
--data-raw '{
  "prompt":"cut dog ",
  "steps":20
}'

Parameters:

o Replace the <service_url> with the endpoint that you obtain in Step 1.
o Replace the <token> with the service token that you obtain in Step 1.

After the command is executed, the system returns the Base64-encoded image.

Use Python to Send a Service Request

Refer to the API to send a service request.

o Sample 1: Use the following Python code to send a service request and obtain an image file.

import requests
import io
import base64
from PIL import Image, PngImagePlugin

url = "<service_url>"

payload = {
    "prompt": "puppy dog",
    "steps": 20,
    "n_iter": 2
}

session = requests.session()
session.headers.update({"Authorization": "<token>"})


response = session.post(url=f'{url}/sdapi/v1/txt2img', json=payload)
if response.status_code != 200:
    raise Exception(response.content)

data = response.json()

# You can obtain the Base64-encoded image by using the synchronous request. We recommend that you use the method to obtain the image address. 
for idx, im in enumerate(data['images']):
    image = Image.open(io.BytesIO(base64.b64decode(im.split(",", 1)[0])))

    png_payload = {
        "image": "data:image/png;base64," + im
    }
    resp = session.post(url=f'{url}/sdapi/v1/png-info', json=png_payload)

    pnginfo = PngImagePlugin.PngInfo()
    pnginfo.add_text("parameters", resp.json().get("info"))
    image.save(f'output-{idx}.png', pnginfo=pnginfo)

Parameters:

  • Replace the <service_url> with the endpoint that you obtain in Step 1.
  • Replace the <token> with the service token that you obtain in Step 1.

After the code is executed, the system returns an image file in the current directory.

o Sample 2: Use the following Python code to send a service request and obtain the image address.

import requests
import oss2

url = "<service_url>"
# The mount_path for OSS that you specified when you deploy the model in EAS. 
mount_path = "/code/stable-diffusion-webui/data-oss"
# The OSS address that you specified when you deploy the model in EAS. 
oss_url = "oss://examplebucket/data-oss"

# The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
# In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
bucket = oss2.Bucket(auth, '<endpoint>', '<examplebucket>')


payload = {
    "alwayson_scripts": {
        "sd_model_checkpoint": "deliberate_v2.safetensors",
        "save_dir": "/code/stable-diffusion-webui/data-oss/outputs"
    },
    "steps": 30,
    "prompt": "girls",
    "batch_size": 1,
    "n_iter": 2,
    "width": 576,
    "height": 576,
    "negative_prompt": "ugly, out of frame"
}


session = requests.session()
session.headers.update({"Authorization": "<token>"})


response = session.post(url=f'{url}/sdapi/v1/txt2img', json=payload)
if response.status_code != 200:
    raise Exception(response.content)

data = response.json()

for idx, path in enumerate(data['parameters']['image_url'].split(',')):
    url = path.replace(mount_path, oss_url)
    print(idx, path, url)

    # Download the object from OSS to the local memory. 
    bucket.get_object_to_file(url[len("oss://<examplebucket>/"):], f'output-{idx}.png')

Parameters:

  • Replace the <service_url> with the endpoint that you obtain in Step 1.
  • Replace the <token> with the service token that you obtain in Step 1.
  • auth: Replace the <yourAccessKeyId> and <yourAccessKeySecret> with the AccessKey ID and AccessKey secret of your Alibaba Cloud account.
  • <endpoint>: The domain name that is used to access OSS. For example, you can set this value to http://oss-cn-hangzhou.aliyuncs.com for the China (Hangzhou) region. For more information, see Regions and endpoints.
  • Replace the <examplebucket> with the name of the existing OSS bucket.

After the code is executed, the system returns the following results. You can go to the OSS console and view the generated image in the OSS path that you specified when you deploy the service.

0 /code/stable-diffusion-webui/data-oss/outputs/txt2img-grids/2023-08-03/grid-b2565642-8ec0-4250-aa9e-f8402e7b87f7.png oss://examplebucket/aohai-singapore/outputs/txt2img-grids/2023-08-03/grid-b2565642-8ec0-4250-aa9e-f8402e7b87f7.png
1 /code/stable-diffusion-webui/data-oss/outputs/txt2img-images/2023-08-03/dc380f1f-efa0-4681-9b1a-298e2513b929-4084873146.png oss://examplebucket/aohai-singapore/outputs/txt2img-images/2023-08-03/dc380f1f-efa0-4681-9b1a-298e2513b929-4084873146.png
2 /code/stable-diffusion-webui/data-oss/outputs/txt2img-images/2023-08-03/3df9fd96-7c5a-487a-8e43-24f87c042806-4084873147.png oss://examplebucket/aohai-singapore/outputs/txt2img-images/2023-08-03/3df9fd96-7c5a-487a-8e43-24f87c042806-4084873147.png

In addition, you can use LoRA and ControlNet data format in request data based on your business requirements.

Use LoRA in the Request Data

You can add the following code in the request body: <lora:yaeMikoRealistic_Genshin:1000>. For more information, see LORA and alwayson_scripts example.

Sample request body:

{
  "prompt":"girls <lora:yaeMikoRealistic_Genshin:1>",
  "steps":20,
  "save_images":true
}

Use ControlNet in the Request Data

You can use the ControlNet data format in the API request to perform common operations on the image in an easier manner, such as keeping the image horizontal or vertical. For more information, see Use ControlNet data format for txt2img.

In addition, EAS supports additional features based on the native SD web UI interface. You can add optional parameters in addition to the required parameters when you send a request. This way, you can use more features and customize your service. For more information, see Additional parameters of API operations section in this article.

Deploy an Asynchronous Service

EAS provides a built-in queue service to help you manage a large number of requests. You can send asynchronous requests and subscribe to the results to manage requests in a more efficient manner. Perform the following steps to deploy an asynchronous service.

1.  Go to the Deploy Service page. For more information, see Deploy a synchronous service section in this article.

2.  In the Configuration Editor section, click JSON Deployment. Enter the following code in the editor field. For more information about how to configure the queue service, see Asynchronous inference and queue service.

{
    "metadata": {
        "name": "sd_async",
        "instance": 1,
        "rpc.work_threads": 1,
        "type": "Async"
    },
    "cloud": {
        "computing": {
            "instance_type": "ml.gu7i.c16m60.1-gu30",
            "instances": null
        },
        "networking": {
            "vpc_id": "vpc-bp1t2wukzskw9139n****",
            "vswitch_id": "vsw-bp12utkudylvp4c70****",
            "security_group_id": "sg-bp11nqxfd0iq6v5g****"
        }
    },
    "queue": {
        "cpu": 1,
        "max_delivery": 1,
        "memory": 4000,
        "resource": ""
    },
    "storage": [
        {
            "oss": {
                "path": "oss://examplebucket/aohai-singapore/",
                "readOnly": false
            },
            "properties": {
                "resource_type": "model"
            },
            "mount_path": "/code/stable-diffusion-webui/data-oss"
        },
        {
            "nfs": {
                "path": "/",
                "server": "0c9624****-fgh60.cn-hangzhou.nas.aliyuncs.com"
            },
            "properties": {
                "resource_type": "model"
            },
            "mount_path": "/code/stable-diffusion-webui/data-nas"
        }
    ],
    "containers": [
        {
            "image": "eas-registry-vpc.cn-hangzhou.cr.aliyuncs.com/pai-eas/stable-diffusion-webui:3.2",
            "script": "./webui.sh --listen --port 8000 --skip-version-check --no-hashing --no-download-sd-model --skip-install --api --nowebui --time-log",
            "port": 8000
        }
    ]
} 

The following changes apply when compared to the deployment of the synchronous services. For more information about how to configure key parameters, see Method 2 in this article.

o Delete the following parameters:

  • metadata.enable_webservice
  • Delete the --filebrowser in the containers.script to accelerate the service startup.

o Add the following parameters:

  • metadata.type: Set the value to Async.
  • metadata.rpc.work_threads: Set the value to 1, which indicates that only one request can be concurrently processed by a single instance.
  • queue.max_delivery: Set the value to 1, which indicates that retries are not allowed after a message processing error occurs.
  • Added --nowebui to accelerate the service startup and --time-log to record the response time in the containers.script parameter.

3.  Click Deploy and wait for the deployment to complete.

Call the Asynchronous Service

After the asynchronous service is deployed, you can send synchronous requests or asynchronous requests based on your business requirements. For more information about how to send synchronous and asynchronous API requests, see Asynchronous inference and queue service.

Send Asynchronous Requests and Subscribe to Results

1.  Obtain the invocation information.

After the service is deployed, click Invocation Method in the Service Type column. In the Invocation Method dialog box, click the Asynchronous Invocation tab. On the Request URL (Internet) tab, obtain the endpoint and token of the service.

3

2.  Send asynchronous requests.

Note

o The sizes of input requests and output results of asynchronous queues are limited. We recommend that you limit the sizes of input requests and output results to no greater than 8 KB. Take note of the following items:

  • If the request data contains an image, we recommend that you use a URL to pass the image information. The SD web UI automatically downloads and parses the image data.
  • We recommend that you use save_dir to specify the path where the generated image is saved to ensure that the original image data is not returned. For more information, see Additional parameters of API operations section in this article.

o By default, EAS cannot access the Internet. If you set the image_link parameter to an image URL, you must configure the network to access the image. For more information about how to configure the network, see Configure network connectivity and Configure Internet access and a whitelist.

Use SDK for Python

Sample code:

import requests

url = "<service_url>"
session = requests.session()
session.headers.update({"Authorization": "<token>"})

prompts = ["cute dog", "cute cat", "cute girl"]

for i in range(5):
    p = prompts[i % len(prompts)]
    payload = {
        "prompt": p,
        "steps": 20,
        "alwayson_scripts": {
            "save_dir": "/code/stable-diffusion-webui/data-oss/outputs/txt2img"
        },
    }
    response = session.post(url=f'{url}/sdapi/v1/txt2img?task_id=txt2img_{i}', json=payload)
    if response.status_code != 200:
        exit(f"send request error:{response.content}")
    else:
        print(f"send {p} success, index is {response.content}")


for i in range(5):
    p = prompts[i % len(prompts)]
    payload = {
        "prompt": p,
        "steps": 20,
        "alwayson_scripts": {
            "save_dir": "/code/stable-diffusion-webui/data-oss/outputs/img2img",
            "image_link": "https://eas-cache-cn-hangzhou.oss-cn-hangzhou-internal.aliyuncs.com/stable-diffusion-cache/tests/boy.png",
        },
    }
    response = session.post(url=f'{url}/sdapi/v1/img2img?task_id=img2img_{i}', json=payload)
    if response.status_code != 200:
        exit(f"send request error:{response.content}")
    else:
        print(f"send {p} success, index is {response.content}")

Parameters:

o Replace the <service_url> with the endpoint that you obtain in Step 1.

o Replace the <token> with the service token that you obtain in Step 1.

Note

o All POST interfaces of the web UI service are supported. The system selects a path to send the request based on specific requirements of the request.

o If you want to pass tags to the service, you can use the URL parameters to specify the tag. For example, you can add a parameter ? task_id=task_abc in the URL parameter of the response to specify the tag as task_id. The information is returned in the tags field in the output of the service.

After the code is executed, a response similar to the following code is returned. Your actual results may vary.

4

Use SDK for Java

Sample code: If you write code in Java, Maven is required to manage projects. You must add the dependency for the client to the pom.xml file. For more information, see SDK for Java.

import com.aliyun.openservices.eas.predict.http.HttpConfig;
import com.aliyun.openservices.eas.predict.http.QueueClient;
import com.aliyun.openservices.eas.predict.queue_client.QueueUser;
import org.apache.commons.lang3.tuple.Pair;

import java.util.HashMap;

public class SDWebuiAsyncPutTest {
    public static void main(String[] args) throws Exception {
        // Create a queue service client. 
        String queueEndpoint = "http://166233998075****.cn-hangzhou.pai-eas.aliyuncs.com";
        String queueToken = "xxxxx==";
        // The input queue consists of the service name and custom request path. 
        String inputQueueName = "<service_name>/sdapi/v1/txt2img";

        // Add data to the input queue. The inference service automatically reads the request data from the input queue. 
        QueueClient inputQueue =
            new QueueClient(queueEndpoint, inputQueueName, queueToken, new HttpConfig(), new QueueUser());
        // Clear queue data!!! Use with caution. 
        // input_queue.clear();

        // Add data to the input queue. 
        int count = 5;
        for (int i = 0; i < count; ++i) {
            // Request data. 
            String data = "{\n" +
                "    \"prompt\": \"cute dog\", \n" +
                "    \"steps\":20,\n" +
                "    \"alwayson_scripts\":{\n" +
                "        \"save_dir\":\"/code/stable-diffusion-webui/data-oss/outputs/txt2img\"\n" +
                "    }\n" +
                "  }";
            // Custom tags. 
            HashMap<String, String> map = new HashMap<String, String>(1);
            map.put("task_id", "txt2img_" + i);
            Pair<Long, String> entry = inputQueue.put(data.getBytes(), map);

            System.out.println(String.format("send success, index is %d, request_id is %s", entry.getKey(), entry.getValue()));
            // The queue service supports multi-priority queues. You can use the put function to set the data priority. The default priority is 0. You can set prioritized data to 1. 
            //  inputQueue.put(data.getBytes(), 0L, null);
        }
        // Close the client. 
        inputQueue.shutdown();


        inputQueueName = "<service_name>/sdapi/v1/img2img";
        inputQueue =
            new QueueClient(queueEndpoint, inputQueueName, queueToken, new HttpConfig(), new QueueUser());
        for (int i = 0; i < count; ++i) {
            // Request data. 
            String data = "{\n" +
                "    \"prompt\": \"cute dog\", \n" +
                "    \"steps\":20,\n" +
                "    \"alwayson_scripts\":{\n" +
                "        \"save_dir\":\"/code/stable-diffusion-webui/data-oss/outputs/img2img\",\n" +
                "        \"image_link\":\"https://eas-cache-cn-hangzhou.oss-cn-hangzhou-internal.aliyuncs.com/stable-diffusion-cache/tests/boy.png\"\n" +
                "    }\n" +
                "  }";
            HashMap<String, String> map = new HashMap<String, String>(1);
            map.put("task_id", "img2img_" + i);
            Pair<Long, String> entry = inputQueue.put(data.getBytes(), map);

            System.out.println(String.format("send success, index is %d, requestId is %s", entry.getKey(), entry.getValue()));
        }

        // Close the client. 
        inputQueue.shutdown();
    }
}

Parameters:

o queueEndpoint: The endpoint obtained in Step 1. For more information, see the sample code.
o queueToken: The service token obtained in Step 1.
o Replace the <service_name> with the name of the deployed asynchronous service.

Note

If you want to pass tags in the service, you can set the tag parameter in the put function. You can refer to the sample code for the usage of custom tags. The tag information is returned in the tag field of the output result.

After the code is executed, a response similar to the following code is returned. Your actual results may vary.

send success, index is 21, request_id is 05ca7786-c24e-4645-8538-83d235e791fe
send success, index is 22, request_id is 639b257a-7902-448d-afd5-f2641ab77025
send success, index is 23, request_id is d6b2e127-eba3-4414-8e6c-c3690e0a487c
send success, index is 24, request_id is 8becf191-962d-4177-8a11-7e4a450e36a7
send success, index is 25, request_id is 862b2d8e-5499-4476-b3a5-943d18614fc5
send success, index is 26, requestId is 9774a4ff-f4c8-40b7-ba43-0b1c1d3241b0
send success, index is 27, requestId is fa536d7a-7799-43f1-947f-71973bf7b221
send success, index is 28, requestId is e69bdd32-5c7b-4c8f-ba3e-e69d2054bf65
send success, index is 29, requestId is c138bd8f-be45-4a47-a330-745fd1569534
send success, index is 30, requestId is c583d4f8-8558-4c8d-95f7-9c3981494007

Process finished with exit code 0

3.  Subscribe to the results of the asynchronous requests.

Use SDK for Python

Sample code:

import json
import oss2

from eas_prediction import QueueClient

sink_queue = QueueClient('139699392458****.cn-hangzhou.pai-eas.aliyuncs.com', 'sd_async/sink')
sink_queue.set_token('<token>')
sink_queue.init()

mount_path = "/code/stable-diffusion-webui/data-oss"
oss_url = "oss://<examplebucket>/aohai-singapore"
# The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
# In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<examplebucket>')


watcher = sink_queue.watch(0, 5, auto_commit=False)
for x in watcher.run():
    if 'task_id' in x.tags:
        print('index {} task_id is {}'.format(x.index, x.tags['task_id']))
    print(f'index {x.index} data is {x.data}')
    sink_queue.commit(x.index)
    try:
        data = json.loads(x.data.decode('utf-8'))
        for idx, path in enumerate(data['parameters']['image_url'].split(',')):
            url = path.replace(mount_path, oss_url)
            # Download the object from OSS to an on-premises memory. 
            bucket.get_object_to_file(url[len("oss://<examplebucket>/"):], f'{x.index}-output-{idx}.png')
            print(f'save {url} to {x.index}-output-{idx}.png')
    except Exception as e:
        print(f'index {x.index} process data error {e}')

Parameters:

o sink_queue: Update the service endpoint and name. For more information about how to obtain the service endpoint, see Obtain the invocation information section in this article.. Configure the parameter based on the sample code.

o <token>: The service token obtained in Step 1.

o Replace the oss_url with the OSS path that you specified when you deploy the service.

o Replace the <examplebucket> with the name of the existing OSS bucket.

o bucket: This section uses the China (Hangzhou) region as an example. Configure the parameter based on your actual situation. For more information, see Regions and endpoints.

Note

o You need to manually commit the operation, or set the auto_commit parameter to true to automatically commit the code.

o If the consumer no longer consumes data, we recommend that you close the consumer to release resources.

o You can also run the cURL command or call the synchronous API operation to obtain the subscription API. For more information, see Asynchronous inference and queue service.

After the code is executed, a response similar to the following code is returned. Your actual results may vary. You can go to the OSS console and view the generated image in the OSS path that you specified when you deploy the service.

index 1 task_id is txt2img_0
index 1 data is b'{"images":[],"parameters":{"id_task":null,"status":0,"image_url":"/code/stable-diffusion-webui/data-oss/outputs/txt2img/txt2img-images/2023-08-16/ad2e270b-dfcc-4ec3-8718-f19824857834-919429454.png","seed":"919429454","error_msg":"","total_time":88.55384421348572},"info":""}'
save oss://<examplebucket>/aohai-singapore/outputs/txt2img/txt2img-images/2023-08-16/ad2e270b-dfcc-4ec3-8718-f19824857834-919429454.png to 1-output-0.png
index 2 task_id is txt2img_1
index 2 data is b'{"images":[],"parameters":{"id_task":null,"status":0,"image_url":"/code/stable-diffusion-webui/data-oss/outputs/txt2img/txt2img-images/2023-08-16/374ceae2-deb5-4448-b213-cfdb11a53892-3273662200.png","seed":"3273662200","error_msg":"","total_time":2.76196551322937},"info":""}'
save oss://<examplebucket>/aohai-singapore/outputs/txt2img/txt2img-images/2023-08-16/374ceae2-deb5-4448-b213-cfdb11a53892-3273662200.png to 2-output-0.png
index 3 task_id is txt2img_2
index 3 data is b'{"images":[],"parameters":{"id_task":null,"status":0,"image_url":"/code/stable-diffusion-webui/data-oss/outputs/txt2img/txt2img-images/2023-08-16/a37a0384-2ed4-42f9-9166-fe0fd80c624c-210444956.png","seed":"210444956","error_msg":"","total_time":2.7492804527282715},"info":""}'
save oss://<examplebucket>/aohai-singapore/outputs/txt2img/txt2img-images/2023-08-16/a37a0384-2ed4-42f9-9166-fe0fd80c624c-210444956.png to 3-output-0.png
index 4 task_id is txt2img_3
index 4 data is b'{"images":[],"parameters":{"id_task":null,"status":0,"image_url":"/code/stable-diffusion-webui/data-oss/outputs/txt2img/txt2img-images/2023-08-16/482dcc64-4848-48f8-b9fd-7f0d3992f1ae-198191449.png","seed":"198191449","error_msg":"","total_time":2.8161191940307617},"info":""}'
save oss://<examplebucket>/aohai-singapore/outputs/txt2img/txt2img-images/2023-08-16/482dcc64-4848-48f8-b9fd-7f0d3992f1ae-198191449.png to 4-output-0.png

Use SDK for Java

Sample code:

import com.aliyun.openservices.eas.predict.http.HttpConfig;
import com.aliyun.openservices.eas.predict.http.QueueClient;
import com.aliyun.openservices.eas.predict.queue_client.DataFrame;
import com.aliyun.openservices.eas.predict.queue_client.QueueUser;
import com.aliyun.openservices.eas.predict.queue_client.WebSocketWatcher;

public class SDWebuiAsyncWatchTest {
    public static void main(String[] args) throws Exception {
        // Create a queue service client. 
        String queueEndpoint = "http://166233998075****.cn-hangzhou.pai-eas.aliyuncs.com";
        String queueToken = "xxxxx==";
        // The name of the output queue consists of the service name and "/sink". 
        String sinkQueueName = "<service_name>/sink";

        // The output queue. The inference service writes the results to the output queue after the service processes the input data. 
        QueueClient sinkQueue =
            new QueueClient(queueEndpoint, sinkQueueName, queueToken, new HttpConfig(), new QueueUser());

        // Clear queue data!!! Use with caution. 
        //  sinkQueue.clear();

        // Subscribe to the queue and obtain queue data. 
        WebSocketWatcher watcher = sinkQueue.watch(0L, 5L, false, false, null);
        try {
            while (true) {
                DataFrame df = watcher.getDataFrame();
                if (df.getTags().containsKey("task_id")) {
                    System.out.println(String.format("task_id = %s", df.getTags().get("task_id")));
                }
                System.out.println(String.format("index = %d, data = %s, requestId = %s", df.getIndex(), new String(df.getData()), df.getTags().get("requestId")));
                sinkQueue.commit(df.getIndex());
            }
        } catch (Exception e) {
            System.out.println("watch error:" + e.getMessage());
            e.printStackTrace();
            watcher.close();
        }

        // Close the client. 
        sinkQueue.shutdown();
    }
}

Parameters:

o queueEndpoint: The endpoint obtained in Step 1. Configure the parameter based on the sample code.

o queueToken: The service token obtained in Step 1.

o Replace the <service_name> with the name of the deployed asynchronous service.

Note

o You need to manually commit the operation, or set the auto_commit parameter to true to automatically commit the code.

o If the consumer no longer consumes data, we recommend that you close the consumer to release resources.

o You can also run the cURL command or call the synchronous API operation to obtain the subscription API. For more information, see Asynchronous inference and queue service.

After the code is executed, a response similar to the following code is returned. Your actual results may vary. You can go to the OSS console and view the generated image in the OSS path that you specified when you deploy the service.

2023-08-04 16:17:31,497 INFO [com.aliyun.openservices.eas.predict.queue_client.WebSocketWatcher] - WebSocketClient Successfully Connects to Server: 1396993924585947.cn-hangzhou.pai-eas.aliyuncs.com/116.62.4.210:80
task_id = txt2img_0
index = 21, data = {"images":[],"parameters":{"id_task":null,"status":0,"image_url":"/code/stable-diffusion-webui/data-oss/outputs/txt2img/txt2img-images/2023-08-04/54363a9d-24a5-41b5-b038-2257d43b8e79-412510031.png","seed":"412510031","error_msg":"","total_time":2.5351321697235107},"info":""}, requestId = 05ca7786-c24e-4645-8538-83d235e791fe
task_id = txt2img_1
index = 22, data = {"images":[],"parameters":{"id_task":null,"status":0,"image_url":"/code/stable-diffusion-webui/data-oss/outputs/txt2img/txt2img-images/2023-08-04/0c646dda-4a53-43f4-97fd-1f507599f6ae-2287341785.png","seed":"2287341785","error_msg":"","total_time":2.6269655227661133},"info":""}, requestId = 639b257a-7902-448d-afd5-f2641ab77025
task_id = txt2img_2
index = 23, data = {"images":[],"parameters":{"id_task":null,"status":0,"image_url":"/code/stable-diffusion-webui/data-oss/outputs/txt2img/txt2img-images/2023-08-04/4d542f25-b9cc-4548-9db2-5addd0366d32-1158414078.png","seed":"1158414078","error_msg":"","total_time":2.6604185104370117},"info":""}, requestId = d6b2e127-eba3-4414-8e6c-c3690e0a487c
task_id = txt2img_3

EAS supports additional features based on the native SD web UI. You can add additional optional parameters in the request data to use the features based on your business requirements. For more information, see Additional parameters of API operations section in this article.

Additional Parameters of API Operations

EAS supports additional features based on the native SD web UI through additional parameters.

• You can specify the SD model, the Variational Autoencoder (VAE) model, and the save directory.

• You can use the URL to specify parameters and obtain the related status code.

• You can access the generated images and the images of the ControlNet format through URLs.

The following section provides sample code.

Sample Requests and Responses of txt2img

The following code provides an example of the request format:

{
      "alwayson_scripts": {
          "sd_model_checkpoint": "deliberate_v2.safetensors",  
          "save_dir": "/code/stable-diffusion-webui/data-oss/outputs",
          "sd_vae": "Automatic"
      },
      "steps": 20,
      "prompt": "girls",          
      "batch_size": 1,                                            
      "n_iter": 2,                                                 
      "width": 576, 
      "height": 576,
      "negative_prompt": "ugly, out of frame"
}

Parameters:

sd_model_checkpoint: Specify the SD model and can automatically switch to a foundation model.

sd_vae: Specify a VAE model.

save_dir: Specify the path to save the generated images.

The following code provides an example on how to send a synchronous request:

# Verify the synchronous request interface and obtain the service call interface. 

curl --location --request POST '<service_url>/sdapi/v1/txt2img' \
--header 'Authorization: <token>' \
--header 'Content-Type: application/json' \
--data-raw '{
      "alwayson_scripts": {
          "sd_model_checkpoint": "deliberate_v2.safetensors",
          "save_dir": "/code/stable-diffusion-webui/data-oss/outputs",
          "sd_vae": "Automatic"
      },
      "prompt": "girls",          
      "batch_size": 1,                                            
      "n_iter": 2,                                                 
      "width": 576, 
      "height": 576,
      "negative_prompt": "ugly, out of frame"
}'

Sample response:

{
  "images": [],
  "parameters": {
    "id_task": "14837",
    "status": 0,
    "image_url": "/code/stable-diffusion-webui/data-oss/outputs/txt2img-grids/2023-07-24/grid-29a67c1c-099a-4d00-8ff3-1ebe6e64931a.png,/code/stable-diffusion-webui/data-oss/outputs/txt2img-images/2023-07-24/74626268-6c81-45ff-90b7-faba579dc309-1146644551.png,/code/stable-diffusion-webui/data-oss/outputs/txt2img-images/2023-07-24/6a233060-e197-4169-86ab-1c18adf04e3f-1146644552.png",
    "seed": "1146644551,1146644552",
    "error_msg": "",
    "total_time": 32.22393465042114
  },
  "info": ""
}

The following code provides an example on how to send an asynchronous request:

curl --location --request POST '<service_url>/sdapi/v1/txt2img' \
--header 'Authorization: <token>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "alwayson_scripts": {
        "sd_model_checkpoint": "deliberate_v2.safetensors",
        "id_task": "14837",
        "uid": "123",
        "save_dir": "tmp/outputs"
    },
    "prompt": "girls",
    "batch_size": 1,
    "n_iter": 2,
    "width": 576,
    "height": 576,
    "negative_prompt": "ugly, out of frame"
}'

Sample Request and Response of img2img

The following code provides an example of the request format:

{
    "alwayson_scripts": {
        "image_link":"https://eas-cache-cn-hangzhou.oss-cn-hangzhou-internal.aliyuncs.com/stable-diffusion-cache/tests/boy.png",
        "sd_model_checkpoint": "deliberate_v2.safetensors",
        "sd_vae": "Automatic",
        "save_dir": "/code/stable-diffusion-webui/data-oss/outputs"
    },
    "prompt": "girl",
    "batch_size": 1,                                            
    "n_iter": 2,                                                 
    "width": 576, 
    "height": 576,
    "negative_prompt": "ugly, out of frame",
    "steps": 20, # Sampling steps
    "seed": 111,   
    "subseed": 111, # Variation seed
    "subseed_strength": 0, # Variation strength
    "seed_resize_from_h": 0, # Resize seed from height
    "seed_resize_from_w": 0, # Resize seed from width
    "seed_enable_extras": false, # Extra
    "sampler_name": "DDIM", # Sampling method
    "cfg_scale": 7.5, # CFG Scale
    "restore_faces": true, # Restore faces
    "tiling": false, # Tiling
    "init_images": [], # image base64 str, default None
    "mask_blur": 4, # Mask blur
    "resize_mode": 1, # 0 just resize, 1 crop and resize, 2 resize and fill, 3 just resize
    "denoising_strength": 0.75, # Denoising strength
    "inpainting_mask_invert": 0, #int, index of ['Inpaint masked', 'Inpaint not masked'], Mask mode
    "inpainting_fill": 0, #index of ['fill', 'original', 'latent noise', 'latent nothing'], Masked content
    "inpaint_full_res": 0, # index of ["Whole picture", "Only masked"], Inpaint area
    "inpaint_full_res_padding": 32, #minimum=0, maximum=256, step=4, value=32, Only masked padding, pixels
    #"image_cfg_scale": 1, # resized by scale
    #"script_name": "Outpainting mk2", # The name of the script. Skip the field if you do not use the script name.
    #"script_args": ["Outpainting", 128, 8, ["left", "right", "up", "down"], 1, 0.05] # The parameters of the script. The field consists of the following parameters: fixed fields, pixels, mask_blur, direction, noise_q, and color_variation.
}

Sample response:

{
    "images":[],
    "parameters":{
        "id_task":"14837",
        "status":0,
        "image_url":"/data/api_test/img2img-grids/2023-06-05/grid-0000.png,/data/api_test/img2img-images/2023-06-05/00000-1003.png,/data/api_test/img2img-images/2023-06-05/00001-1004.png",
        "seed":"1003,1004",
        "error_msg":""
    },
    "info":""
}

Data format of ControlNet for txt2img

The following code provides an example of the request format:

{
    "alwayson_scripts": {
        "sd_model_checkpoint": "deliberate_v2.safetensors", # The name of the model. 
        "save_dir": "/code/stable-diffusion-webui/data-oss/outputs",
        "controlnet":{
            "args":[
                {
                    "image_link": "https://pai-aigc-dataset.oss-cn-hangzhou.aliyuncs.com/pixabay_images/00008b87bf3ff6742b8cf81c358b9dbc.jpg",
                    "enabled": true, 
                    "module": "canny", 
                    "model": "control_v11p_sd15_canny", 
                    "weight": 1, 
                    "resize_mode": "Crop and Resize", 
                    "low_vram": false, 
                    "processor_res": 512, 
                    "threshold_a": 100, 
                    "threshold_b": 200, 
                    "guidance_start": 0, 
                    "guidance_end": 1, 
                    "pixel_perfect": true, 
                    "control_mode": "Balanced", 
                    "input_mode": "simple", 
                    "batch_images": "", 
                    "output_dir": "", 
                    "loopback": false
                }
            ]
        }
    },
    # Key parameters.
    "prompt": "girls",          
    "batch_size": 1,                                            
    "n_iter": 2,                                                 
    "width": 576, 
    "height": 576,
    "negative_prompt": "ugly, out of frame"
}

Sample response:

{
    "images":[],
    "parameters":{
        "id_task":"14837",
        "status":0,
        "image_url":"/data/api_test/txt2img-grids/2023-06-05/grid-0007.png,/data/api_test/txt2img-images/2023-06-05/00014-1003.png,/data/api_test/txt2img-images/2023-06-05/00015-1004.png",
        "seed":"1003,1004",
        "error_msg":"",
        "image_mask_url":"/data/api_test/controlnet_mask/2023-06-05/00000.png,/data/api_test/controlnet_mask/2023-06-05/00001.png"
    },
    "info":""
}
0 1 0
Share on

You may also like

Comments

Related Products