快速搭建數字人視頻生成接口
借助 Live Portrait(實時肖像)在 ComfyUI 中快速搭建文本生成數字人視頻(文本生成視頻,aigc 生成視頻)
方案概覽
用戶自己手動在智作工坊控制臺創建對應的應用,調試需要的工作流,并且發布為一個可以調用的接口,之后使用對應的語言的 SDK 接入,并且調用獲取到 ComfyUI 任務的結果。基于智作工坊的控制臺和提供的各語言版本 SDK,可以快速調試自己需要的工作流,并且部署為API接口供調用。
部署準備
開始部署前,請按以下指引完成賬號申請、賬號充值。
準備賬號
如果您還沒有阿里云賬號,請訪問阿里云賬號注冊頁面,根據頁面提示完成注冊。阿里云賬號是您使用云資源的付費實體,因此是部署方案的必要前提。
開通智作工坊
參考智作工坊服務開通文檔:服務開通
快速體驗
準備工作流
保存下面的內容到t2v.json
文件:
{
"last_node_id": 199,
"last_link_id": 31,
"nodes": [
{
"id": 8,
"type": "VHS_LoadVideo",
"pos": {
"0": 70,
"1": 0
},
"size": [
250,
620
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [
{
"name": "meta_batch",
"type": "VHS_BatchManager",
"link": null,
"label": "批次管理"
},
{
"name": "vae",
"type": "VAE",
"link": null
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
21
],
"shape": 3,
"label": "圖像"
},
{
"name": "frame_count",
"type": "INT",
"links": null,
"slot_index": 1,
"shape": 3,
"label": "幀計數"
},
{
"name": "audio",
"type": "AUDIO",
"links": [
31
],
"slot_index": 2,
"shape": 3,
"label": "音頻"
},
{
"name": "video_info",
"type": "VHS_VIDEOINFO",
"links": null,
"shape": 3,
"label": "視頻信息"
}
],
"properties": {
"Node name for S&R": "VHS_LoadVideo"
},
"widgets_values": {
"video": "_sp_auto_upload_01j7fhv11v4vmfydkhnpz8h67w.mp4",
"force_rate": 0,
"force_size": "Disabled",
"custom_width": 512,
"custom_height": 512,
"frame_load_cap": 0,
"skip_first_frames": 0,
"select_every_nth": 1,
"choose video to upload": "image",
"videopreview": {
"hidden": false,
"paused": false,
"params": {
"filename": "_sp_auto_upload_01j7fhv11v4vmfydkhnpz8h67w.mp4",
"type": "input",
"format": "video/mp4",
"frame_load_cap": 0,
"skip_first_frames": 0,
"force_rate": 0,
"select_every_nth": 1
},
"muted": false
}
}
},
{
"id": 196,
"type": "LoadImage",
"pos": {
"0": 30,
"1": 680
},
"size": {
"0": 320,
"1": 310
},
"flags": {},
"order": 1,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
13
],
"shape": 3,
"label": "圖像"
},
{
"name": "MASK",
"type": "MASK",
"links": null,
"shape": 3,
"label": "遮罩"
}
],
"properties": {
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"_sp_auto_upload_01j7fhtp8s3k82dyma6479jk9b.png",
"image"
]
},
{
"id": 165,
"type": "ImageResizeKJ",
"pos": {
"0": 390,
"1": 680
},
"size": {
"0": 320,
"1": 270
},
"flags": {},
"order": 4,
"mode": 0,
"inputs": [
{
"name": "image",
"type": "IMAGE",
"link": 13,
"label": "圖像"
},
{
"name": "get_image_size",
"type": "IMAGE",
"link": null,
"label": "參考圖像大小"
},
{
"name": "width_input",
"type": "INT",
"link": null,
"widget": {
"name": "width_input"
},
"label": "寬度"
},
{
"name": "height_input",
"type": "INT",
"link": null,
"widget": {
"name": "height_input"
},
"label": "高度"
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
17,
22
],
"shape": 3,
"label": "圖像"
},
{
"name": "width",
"type": "INT",
"links": null,
"shape": 3,
"label": "寬度"
},
{
"name": "height",
"type": "INT",
"links": null,
"shape": 3,
"label": "高度"
}
],
"properties": {
"Node name for S&R": "ImageResizeKJ"
},
"widgets_values": [
512,
512,
"lanczos",
true,
2,
0,
0,
"disabled"
]
},
{
"id": 198,
"type": "LivePortraitLoadMediaPipeCropper",
"pos": {
"0": 350,
"1": 320
},
"size": {
"0": 320,
"1": 80
},
"flags": {},
"order": 2,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "cropper",
"type": "LPCROPPER",
"links": [
16
],
"shape": 3,
"label": "裁剪框架"
}
],
"properties": {
"Node name for S&R": "LivePortraitLoadMediaPipeCropper"
},
"widgets_values": [
"CUDA",
true
]
},
{
"id": 190,
"type": "LivePortraitProcess",
"pos": {
"0": 1120,
"1": 110
},
"size": {
"0": 430,
"1": 330
},
"flags": {},
"order": 6,
"mode": 0,
"inputs": [
{
"name": "pipeline",
"type": "LIVEPORTRAITPIPE",
"link": 18,
"label": "LivePortrait管線"
},
{
"name": "crop_info",
"type": "CROPINFO",
"link": 19,
"label": "裁剪信息"
},
{
"name": "source_image",
"type": "IMAGE",
"link": 20,
"label": "原圖像"
},
{
"name": "driving_images",
"type": "IMAGE",
"link": 21,
"label": "驅動圖像"
},
{
"name": "opt_retargeting_info",
"type": "RETARGETINGINFO",
"link": null,
"label": "重定向信息(可選)"
}
],
"outputs": [
{
"name": "cropped_image",
"type": "IMAGE",
"links": [
23
],
"shape": 3,
"label": "裁剪圖像"
},
{
"name": "output",
"type": "LP_OUT",
"links": [
24
],
"shape": 3,
"label": "LivePOrtrait輸出"
}
],
"properties": {
"Node name for S&R": "LivePortraitProcess"
},
"widgets_values": [
false,
0.03,
true,
1,
"constant",
"relative",
0.000003,
false,
1
]
},
{
"id": 191,
"type": "LivePortraitComposite",
"pos": {
"0": 1600,
"1": 130
},
"size": {
"0": 360,
"1": 90
},
"flags": {},
"order": 7,
"mode": 0,
"inputs": [
{
"name": "source_image",
"type": "IMAGE",
"link": 22,
"label": "原圖像"
},
{
"name": "cropped_image",
"type": "IMAGE",
"link": 23,
"label": "裁剪圖像"
},
{
"name": "liveportrait_out",
"type": "LP_OUT",
"link": 24,
"label": "LivePOrtrait輸出"
},
{
"name": "mask",
"type": "MASK",
"link": null,
"label": "遮罩"
}
],
"outputs": [
{
"name": "full_images",
"type": "IMAGE",
"links": [
14
],
"shape": 3,
"label": "圖像"
},
{
"name": "mask",
"type": "MASK",
"links": null,
"shape": 3,
"label": "遮罩"
}
],
"properties": {
"Node name for S&R": "LivePortraitComposite"
}
},
{
"id": 189,
"type": "LivePortraitCropper",
"pos": {
"0": 740,
"1": 350
},
"size": {
"0": 330,
"1": 240
},
"flags": {},
"order": 5,
"mode": 0,
"inputs": [
{
"name": "pipeline",
"type": "LIVEPORTRAITPIPE",
"link": 15,
"label": "LivePortrait管線"
},
{
"name": "cropper",
"type": "LPCROPPER",
"link": 16,
"label": "裁剪框架"
},
{
"name": "source_image",
"type": "IMAGE",
"link": 17,
"label": "原圖像"
}
],
"outputs": [
{
"name": "cropped_image",
"type": "IMAGE",
"links": [
20
],
"shape": 3
},
{
"name": "crop_info",
"type": "CROPINFO",
"links": [
19
],
"shape": 3,
"label": "裁剪信息"
}
],
"properties": {
"Node name for S&R": "LivePortraitCropper"
},
"widgets_values": [
512,
2.3000000000000003,
0,
-0.125,
0,
"large-small",
true
]
},
{
"id": 168,
"type": "VHS_VideoCombine",
"pos": {
"0": 1660,
"1": 300
},
"size": [
210,
500
],
"flags": {},
"order": 8,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 14,
"label": "圖像"
},
{
"name": "audio",
"type": "AUDIO",
"link": 31,
"label": "音頻"
},
{
"name": "meta_batch",
"type": "VHS_BatchManager",
"link": null,
"label": "批次管理"
},
{
"name": "vae",
"type": "VAE",
"link": null
}
],
"outputs": [
{
"name": "Filenames",
"type": "VHS_FILENAMES",
"links": null,
"shape": 3,
"label": "文件名"
}
],
"properties": {
"Node name for S&R": "VHS_VideoCombine"
},
"widgets_values": {
"frame_rate": 30,
"loop_count": 0,
"filename_prefix": "LivePortrait/",
"format": "video/h264-mp4",
"pix_fmt": "yuv420p",
"crf": 19,
"save_metadata": true,
"pingpong": false,
"save_output": true,
"videopreview": {
"hidden": false,
"paused": false,
"params": {
"filename": "_sp_auto_upload_https://sd-fc-prod.oss-cn-shanghai.aliyuncs.com/comfy%2Foutput%2FLivePortraitd869915d5e824dedaf9feed80af48eb4_00001-audio.mp4?Expires=1728618753&OSSAccessKeyId=LTAI5tBsDGhKWWwT6sC7****&Signature=5tFCnnJIj8aENes8435sLmKbFwM%3D",
"format": "video/h264-mp4",
"frame_rate": 30,
"object_key": "comfy/output/LivePortraitd869915d5e824dedaf9feed80af48eb4_00001-audio.mp4",
"subfolder": "",
"type": "output"
},
"muted": false
}
}
},
{
"id": 1,
"type": "DownloadAndLoadLivePortraitModels",
"pos": {
"0": 80,
"1": -150
},
"size": {
"0": 320,
"1": 80
},
"flags": {},
"order": 3,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "live_portrait_pipe",
"type": "LIVEPORTRAITPIPE",
"links": [
15,
18
],
"shape": 3,
"label": "LivePortrait管線"
}
],
"properties": {
"Node name for S&R": "DownloadAndLoadLivePortraitModels"
},
"widgets_values": [
"fp16",
"human"
]
}
],
"links": [
[
13,
196,
0,
165,
0,
"IMAGE"
],
[
14,
191,
0,
168,
0,
"IMAGE"
],
[
15,
1,
0,
189,
0,
"LIVEPORTRAITPIPE"
],
[
16,
198,
0,
189,
1,
"LPCROPPER"
],
[
17,
165,
0,
189,
2,
"IMAGE"
],
[
18,
1,
0,
190,
0,
"LIVEPORTRAITPIPE"
],
[
19,
189,
1,
190,
1,
"CROPINFO"
],
[
20,
189,
0,
190,
2,
"IMAGE"
],
[
21,
8,
0,
190,
3,
"IMAGE"
],
[
22,
165,
0,
191,
0,
"IMAGE"
],
[
23,
190,
0,
191,
1,
"IMAGE"
],
[
24,
190,
1,
191,
2,
"LP_OUT"
],
[
31,
8,
2,
168,
1,
"*"
]
],
"groups": [],
"config": {},
"extra": {
"ds": {
"scale": 0.5559917313492244,
"offset": [
249.9019008932993,
305.3913911427086
]
}
},
"version": 0.4
}
新建工作流
點擊新建工作流
填寫工作流信息,以及選擇需要的工作流模板,這里選擇本地工作流文件導入,點擊確認
點擊之后將會跳轉到工作流編輯界面,等待頁面加載完畢之后,顯示如下:
運行查看效果
點擊右上角運行工作流查看效果
等待工作流執行
執行結束,查看結果如下圖
部署工作流為接口
發布工作流
確認工作流可以執行得到結果后,點擊發布,進入發布菜單
填入版本描述:填入文生視頻測試
設置工作流入參:在這里可以設置接口服務對外暴露的參數,其他未暴露的參數值默認使用工作流中的值。若調用時為傳遞設置的參數,也默認是工作流中的參數。
點擊下方添加按鈕,可以添加新的參數
添加之后確認設置好的參數,含義如下,注意
#3
會顯示在工作流右上角,方便對應關系如果需要修改參數
點擊字段對應的編輯,可以編輯參數別名
編輯態:
編輯好之后,回車保存
發布工作流:確認無誤之后,點擊提交發布。
發布之后可以看到生成對應的接口版本管理信息
為工作流指定別名
點擊別名管理tab,點擊新建別名按鈕,填寫接口調用別名名稱,選擇別名當前對應的主版本,后續更新接口版本只需要在此替換版本即可,無需修改代碼中的版本ID。
點擊確認,得到如下效果:
復制對應的別名備用,這里是
t2v_0912
應用創建獲取AKSK
接口發布之后,想要調用接口,需要先新建應用,使用應用的AKSK通過SDK調用。打開智作工坊控制臺應用管理tab頁
點擊右上角創建應用
填寫應用名稱以及應用類型,點擊確認
確認后會自動跳轉應用詳情頁,復制對應的AK、SK備用
代碼調用
獲取到應用的 AKSK、以及工作流別名,需要使用對應語言的SDK調用,這里以Python為例,其余語言參考各語言SDK參考
參考指南完成接入:Python接入指南
替換 main.py 其中的 AKSK、工作流ID、工作流別名和參數如下:
from client import Client from proto import ComfyRequest, ComfyResponse, PredictResultResponse, ProgressResponse import time import json cli = Client( endpoint="openai.edu-aliyun.com", app_key="替換AK", app_secret="替換SK" ) # 原始調用方法 def call(url, body, method='POST', headers=None): # 忽略 def comfy_prompt(prompt: ComfyRequest, custom_resource_config_id='default') -> ComfyResponse: # 忽略內容 if __name__ == '__main__': begin = time.time() # 工作流別名 alias_id = "替換為工作流別名" workflow_id = "替換為控制臺上的工作流 ID" params = { "prompt": "提示詞" } result = comfy_prompt(ComfyRequest(alias_id=alias_id, workflow_id=workflow_id, inputs=params)) print("生圖結果:" + str(result)) print("時間消耗: %.2fs" % (time.time() - begin))
查看效果
執行之后可以獲取結果,示例結果為:
{
"status": 10,
"err_code": null,
"err_message": null,
"sub_err_code": null,
"sub_err_message": null,
"api_invoke_id": "i_66e2605219c46d002564ff0f",
"data": {
"task_id": "01j7j4epagfdab24jbsknt9q97",
"images": [
"http://xxxxx"
],
"info": {},
"parameters": null,
"status": "succeeded",
"imgs_bytes": null
}
}