如何基于火山引擎弹性容器快速部署 MagicAnimate 应用
火山引擎弹性容器实例(VCI)是一种 Serverless 和容器化的计算服务,旨在帮助企业控制云成本、专注于构建应用本身。
来源 | 火山引擎云原生团队
根据相关论文 MagicAnimate: Temporally Consistent Human Image Animation using Diffusion Model 介绍,MagicAnimate 在 TikTok 舞蹈数据集上,生成的视频保真度比最强基线提高了超过 38%。
构建容器镜像
制作 VCI 容器镜像缓存
通过 VCI 部署 magic-animate 应用
浏览器请求测试效果
什么是 VCI
火山引擎弹性容器实例(VCI)是一种 Serverless 和容器化的计算服务,它旨在帮助企业控制云成本、专注于构建应用本身——无需购买和管理底层云服务器等基础设施,仅为容器实际运行消耗的资源付费。
构建容器镜像
python3from huggingface_hub import snapshot_downloadsnapshot_download(repo_id="runwayml/stable-diffusion-v1-5",local_dir="/root/magic-animate/sdv15")snapshot_download(repo_id="stabilityai/sd-vae-ft-mse",local_dir="/root/magic-animate/vae")snapshot_download(repo_id="zcxu-eric/MagicAnimate",local_dir="/root/magic-animate/MagicAnimate")
将相关模型放到项目的 pretrained_models 目录下,目录结构 Dockerfile 如下所示(此处省略具体镜像制作过程),同时将模型也打包到容器镜像中。
FROM paas-cn-beijing.cr.volces.com/cuda/cuda:11.4.3-devel-ubuntu20.04-torchLABEL org.opencontainers.image.authors="[email protected]"RUN apt-get update && apt-get install -y gitRUN git clone https://github.com/magic-research/magic-animate.git && cd magic-animate && pip3 install -r requirements.txtCOPY demo/gradio_animate.py magic-animate/demo/RUN mkdir -p magic-animate/pretrained_modelsCOPY pretrained_models magic-animate/pretrained_modelsWORKDIR magic-animateCMD ["python3","-m","demo.gradio_animate"]
需要修改的demo/gradio_animate.py如下,制作容器镜像时会将该文件覆盖项目原有的相同名称的文件,达到修改监听地址的目的。
# Copyright 2023 ByteDance and/or its affiliates.## Copyright (2023) MagicAnimate Authors## ByteDance, its affiliates and licensors retain all intellectual# property and proprietary rights in and to this material, related# documentation and any modifications thereto. Any use, reproduction,# disclosure or distribution of this material and related documentation# without an express license agreement from ByteDance or# its affiliates is strictly prohibited.import argparseimport imageioimport numpy as npimport gradio as grfrom PIL import Imagefrom demo.animate import MagicAnimateanimator = MagicAnimate()def animate(reference_image, motion_sequence_state, seed, steps, guidance_scale):return animator(reference_image, motion_sequence_state, seed, steps, guidance_scale)with gr.Blocks() as demo:gr.HTML("""<div style="display: flex; justify-content: center; align-items: center; text-align: center;"><a href="https://github.com/magic-research/magic-animate" style="margin-right: 20px; text-decoration: none; display: flex; align-items: center;"></a><div><h1 >MagicAnimate: Temporally Consistent Human Image Animation using Diffusion Model</h1><h5 style="margin: 0;">If you like our project, please give us a star ✨ on Github for the latest update.</h5><div style="display: flex; justify-content: center; align-items: center; text-align: center;><a href="https://arxiv.org/abs/2311.16498"><img src="https://img.shields.io/badge/Arxiv-2311.16498-red"></a><a href='https://showlab.github.io/magicanimate'><img src='https://img.shields.io/badge/Project_Page-MagicAnimate-green' alt='Project Page'></a><a href='https://github.com/magic-research/magic-animate'><img src='https://img.shields.io/badge/Github-Code-blue'></a></div></div></div>""")animation = gr.Video(format="mp4", label="Animation Results", autoplay=True)with gr.Row():reference_image = gr.Image(label="Reference Image")motion_sequence = gr.Video(format="mp4", label="Motion Sequence")with gr.Column():random_seed = gr.Textbox(label="Random seed", value=1, info="default: -1")sampling_steps = gr.Textbox(label="Sampling steps", value=25, info="default: 25")guidance_scale = gr.Textbox(label="Guidance scale", value=7.5, info="default: 7.5")submit = gr.Button("Animate")def read_video(video):reader = imageio.get_reader(video)fps = reader.get_meta_data()['fps']return videodef read_image(image, size=512):return np.array(Image.fromarray(image).resize((size, size)))# when user uploads a new videomotion_sequence.upload(read_video,motion_sequence,motion_sequence)# when `first_frame` is updatedreference_image.upload(read_image,reference_image,reference_image)# when the `submit` button is clickedsubmit.click(animate,[reference_image, motion_sequence, random_seed, sampling_steps, guidance_scale],animation)# Examplesgr.Markdown("## Examples")gr.Examples(examples=[["inputs/applications/source_image/monalisa.png", "inputs/applications/driving/densepose/running.mp4"],["inputs/applications/source_image/demo4.png", "inputs/applications/driving/densepose/demo4.mp4"],["inputs/applications/source_image/0002.png", "inputs/applications/driving/densepose/demo4.mp4"],["inputs/applications/source_image/dalle2.jpeg", "inputs/applications/driving/densepose/running2.mp4"],["inputs/applications/source_image/dalle8.jpeg", "inputs/applications/driving/densepose/dancing2.mp4"],["inputs/applications/source_image/multi1_source.png", "inputs/applications/driving/densepose/multi_dancing.mp4"],],inputs=[reference_image, motion_sequence],outputs=animation,)demo.launch(server_name='0.0.0.0')#修改监听地址,默认为127.0.0.1
制作 VCI 容器镜像缓存
火山引擎提供镜像加速方案,可以将镜像拉取用时从分钟级降低到秒级,帮助用户大幅提升效率(详见《AIGC 推理加速:火山引擎镜像加速实践》)。这里我们直接使用加速效果最好的镜像缓存方案。
通过火山引擎控制台,我们可以非常快速地制作容器镜像缓存,极大提升镜像拉取速度。
通过 VCI 部署 magic-animate 应用
apiVersion: apps/v1kind: Deploymentmetadata:name: magic-animatenamespace: defaultspec:progressDeadlineSeconds: 600replicas: 1revisionHistoryLimit: 10selector:matchLabels:app: magic-animatestrategy:rollingUpdate:maxSurge: 25%maxUnavailable: 25%type: RollingUpdatetemplate:metadata:annotations:vci.vke.volcengine.com/preferred-instance-types: vci.ini2.26c-243givke.volcengine.com/burst-to-vci: enforcecreationTimestamp: nulllabels:app: magic-animatespec:containers:- image: paas-cn-beijing.cr.volces.com/aigc/magic-animate:v1imagePullPolicy: IfNotPresentname: appresources:limits:nvidia.com/gpu: "1"terminationMessagePath: /dev/termination-logterminationMessagePolicy: FilednsPolicy: ClusterFirstnodeSelector:kubernetes.io/hostname: vci-node1-cn-beijing-brestartPolicy: AlwaysschedulerName: default-schedulersecurityContext: {}terminationGracePeriodSeconds: 30
apiVersion: v1kind: Servicemetadata:annotations:service.beta.kubernetes.io/volcengine-loadbalancer-address-type: PUBLICservice.beta.kubernetes.io/volcengine-loadbalancer-bandwidth: "10"service.beta.kubernetes.io/volcengine-loadbalancer-eip-billing-type: "3"service.beta.kubernetes.io/volcengine-loadbalancer-health-check-flag: "off"service.beta.kubernetes.io/volcengine-loadbalancer-ip-version: ipv4service.beta.kubernetes.io/volcengine-loadbalancer-isp-type: BGPservice.beta.kubernetes.io/volcengine-loadbalancer-name: magic-animate-lbservice.beta.kubernetes.io/volcengine-loadbalancer-pass-through: "true"service.beta.kubernetes.io/volcengine-loadbalancer-scheduler: wrrservice.beta.kubernetes.io/volcengine-loadbalancer-spec: small_1service.beta.kubernetes.io/volcengine-loadbalancer-subnet-id: subnet-mjn0iia7j6yo5smt1a9fcz5vname: magic-animate-svcnamespace: defaultspec:allocateLoadBalancerNodePorts: trueexternalTrafficPolicy: LocalinternalTrafficPolicy: ClusteripFamilies:- IPv4ipFamilyPolicy: SingleStackports:- port: 80protocol: TCPtargetPort: 7860selector:app: magic-animatesessionAffinity: Nonetype: LoadBalancer
浏览器请求测试效果
我们使用步骤三中创建服务获取到的公网 IP,浏览器访问 http://${公网ip} 就可以请求到我们的 Web 界面。
我们选择原始图片和 Motion Sequence,等待生成视频。视频生成完成后点击播放查看效果。
小结
回望 2023 年,大模型和 AIGC 已经开始进行初期的商业化探索,慢慢脱虚向实,走向产业落地。到 2024 年,这一趋势势必将进一步加速。
根据 Gartner 对于未来生成式 AI 的预测,到 2026 年,超过 80% 的企业都会接入生成式 AI 或大模型。而这种变化不会局限在单一技术,也会反映在企业架构之上。
面对这一趋势,火山引擎云原生团队依托字节跳动云原生技术实践和企业服务经验,正在不断迭代和创新解决方案,以提供更高稳定性和更弹性的云原生 AI 基建,帮助企业不断降低 AI 技术开发和应用的门槛。
扫码咨询
火山引擎云原生团队主要负责火山引擎公有云及私有化场景中 PaaS 类产品体系的构建,结合字节跳动多年的云原生技术栈经验和最佳实践沉淀,帮助企业加速数字化转型和创新。产品包括容器服务、镜像仓库、分布式云原生平台、函数服务、服务网格、持续交付、可观测服务等。