跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI算法

阿里开源 Z-Image-Turbo 本地 Docker 部署指南

介绍如何在本地使用 Docker 部署阿里开源的 Z-Image-Turbo 图像生成模型。内容包括环境准备、模型下载、FastAPI 后端服务构建、WebUI 前端开发以及镜像打包运行。通过配置 NVIDIA 显卡加速,实现本地化无水印图片生成,支持自定义提示词与参数调整,适合拥有 RTX 3090 等高性能显卡的用户进行离线推理部署。

星落发布于 2026/3/26更新于 2026/9/915K 浏览
阿里开源 Z-Image-Turbo 本地 Docker 部署指南

环境准备

  1. 操作系统:Ubuntu 24.04
  2. 显卡:RTX 3090 (24G) 或同等性能 NVIDIA GPU
  3. 基础软件:已安装 Docker 并配置 nvidia-container-toolkit

模型获取

从官方仓库下载 Tongyi-MAI/Z-Image-Turbo 模型权重文件,并解压至服务器指定目录(例如 /data/models/Z-Image-Turbo)。

构建服务代码

1. 后端服务 (zimage_server.py)

新建 Python 文件,代码如下。可根据实际情况修改端口和分辨率。

import os
import torch
import base64
import logging
import uvicorn
from io import BytesIO
from contextlib import asynccontextmanager
from fastapi import FastAPI, Form, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from diffusers import DiffusionPipeline
from fastapi.responses import FileResponse

# --- 配置 ---
MODEL_PATH = "/data/models/Z-Image-Turbo"
HOST = "0.0.0.0"
PORT = 8000
DEVICE = "cuda"

# 日志配置
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s')
logger = logging.getLogger(__name__)
ml_models = {}

@asynccontextmanager
async def lifespan(app: FastAPI):
    logger.info(f"正在加载模型:{MODEL_PATH} ...")
    try:
        
        
        
        dtype = torch.bfloat16  torch.cuda.is_bf16_supported()  torch.float16
        pipe = DiffusionPipeline.from_pretrained(
            MODEL_PATH,
            torch_dtype=dtype,
            use_safetensors=
        )
        
        pipe.to(DEVICE)
        
        
        
        ml_models[] = pipe
        logger.info()
     Exception  e:
        logger.error()
         e
    
    ml_models.clear()
     torch.cuda.is_available():
        torch.cuda.empty_cache()

app = FastAPI(lifespan=lifespan)
app.add_middleware(
    CORSMiddleware,
    allow_origins=[],
    allow_credentials=,
    allow_methods=[],
    allow_headers=[]
)


  ():
     FileResponse()


  ():
        ml_models:
         HTTPException(status_code=, detail=)
    logger.info()
    :
        pipe = ml_models[]
        
        image = pipe(
            prompt=prompt,
            height=,      
            width=,
            num_inference_steps=,  
            guidance_scale=,     
            output_type=
        ).images[]
        buffer = BytesIO()
        image.save(buffer, =)
        base64_img = base64.b64encode(buffer.getvalue()).decode()
         {: base64_img}
     Exception  e:
        logger.error()
         HTTPException(status_code=, detail=(e))

 __name__ == :
    uvicorn.run(app, host=HOST, port=PORT)

目录

  1. 环境准备
  2. 模型获取
  3. 构建服务代码
  4. 1. 后端服务 (zimage_server.py)
  5. --- 配置 ---
  6. 日志配置
  7. 2. 前端页面 (index.html)
  8. 镜像构建与运行
  9. 1. 构建 Dockerfile
  10. 1. 基础镜像:改用 CUDA 12.4 (目前 PyTorch 支持最好的高版本)
  11. 即使物理机驱动是 CUDA 13,容器内用 CUDA 12.4 也是完全兼容的
  12. 2. 环境变量设置
  13. 显存优化参数
  14. 设置默认模型路径,方便 Python 代码读取
  15. 3. 安装系统依赖
  16. 增加了 git (pip 安装 git+... 需要) 和 curl
  17. 4. 升级 pip
  18. 5. 安装 PyTorch (CUDA 13 版本)
  19. 这里使用了 cu130 的源,确保下载到支持 GPU 的版本
  20. 6. 安装 Diffusers 和相关 AI 依赖
  21. 补充了 sentencepiece 和 protobuf (Transformers 必须)
  22. 7. 安装 Web 服务依赖
  23. 8. 复制代码文件
  24. 如果你有 index.html 也复制进去,没有则注释掉
  25. 9. 暴露端口
  26. 10. 启动命令
  27. 确保 host 是 0.0.0.0 才能被外部访问
  28. 2. 构建镜像
  29. 3. 运行容器
  30. 4. 验证运行状态
  31. 使用 Web 界面生图

更多推荐文章

查看全部
  • 常用技术资源与开源社区链接汇总
  • 使用 wxauto 与百度千帆大模型构建微信聊天机器人
  • Spring Boot WebClient 集成大模型 API:OpenAI、文心一言、通义千问
  • XGBoost+SHAP 可解释性分析回归预测及可视化算法
  • Copilot 四大模式详解:Ask、Edit、Agent 与 Plan 的核心区别
  • Linux 进程优先级详解:调度规则与调整方法
  • llama.cpp 量化模型部署实战:从模型转换到 API 服务
  • OpenClaw + Ollama 集成指南:本地私有化部署 LLM
  • ORB-SLAM3 开源视觉与视觉惯性 SLAM 库详解
  • Diffusion Transformer(DiT):用 ViT 替代 U-Net 用于视频生成与机器人动作预测
  • 大模型(LLM)前沿研究论文合集:检索增强、压缩与评估
  • AIGC 技术现状、应用场景与未来趋势
  • 使用 Python SDK 调用扣子(Coze)工作流
  • 10 款论文 AIGC 降重工具实测对比
  • 法奥机器人基础操作与编程指南
  • 大模型基本概念解析:定义、分类与发展历程
  • 企业级招聘数据采集:基于 Bright Data AI Studio 的自动化爬虫方案
  • 主流无人机倾斜摄影三维建模服务商盘点
  • Z-Image-Turbo 镜像本地部署:快速启动 AI 绘画服务
  • Qwen2.5-7B-Instruct 工具调用集成心知天气示例

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

# --- 官方代码逻辑移植 1: 精度设置 ---
# 官方建议使用 bfloat16 以获得最佳性能并防止黑图
# 如果你的显卡比较旧(不支持 bfloat16),请改回 torch.float16
if
else
True
# 移动到 GPU
# --- 官方代码逻辑移植 2: 内存优化 ---
# 如果显存不够,取消下面这行的注释
# pipe.enable_model_cpu_offload()
"pipe"
f">>> 模型加载成功 (Precision: {dtype})"
except
as
f"模型加载失败:{e}"
raise
yield
if
"*"
True
"*"
"*"
@app.get("/")
async
def
index
return
"/workspace/index.html"
@app.post("/api/generate")
async
def
generate
prompt: str = Form(...)
if
"pipe"
not
in
raise
503
"Model not loaded"
f"收到任务:{prompt[:50]}..."
try
"pipe"
# --- 官方代码逻辑移植 3: 关键推理参数 ---
1024
# 官方默认分辨率
1024
9
# 官方设置:Turbo 模型只需要很少的步数
0.0
# 【核心修复】Turbo 模型必须设为 0,否则会黑图或乱码
"pil"
0
format
"PNG"
return
"image"
except
as
f"生成出错:{e}"
raise
500
str
if
"__main__"

2. 前端页面 (index.html)

新建 HTML 文件,注意将 API 请求地址中的 IP 替换为实际服务器 IP。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>Z-Image-Turbo WebUI</title>
    <style>
        :root {
            --primary-color: #4a90e2;
            --primary-hover: #357abd;
            --bg-color: #f5f7fa;
            --card-bg: #ffffff;
            --text-color: #333333;
            --border-radius: 12px;
            --shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
        }
        body {
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
            background-color: var(--bg-color);
            color: var(--text-color);
            margin: 0;
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 20px;
        }
        .container {
            background-color: var(--card-bg);
            padding: 40px;
            border-radius: var(--border-radius);
            box-shadow: var(--shadow);
            width: 100%;
            max-width: 550px;
            text-align: center;
            transition: transform 0.3s ease;
        }
        h2 {
            margin-top: 0;
            margin-bottom: 30px;
            color: #2c3e50;
            font-weight: 700;
            letter-spacing: -0.5px;
        }
        .input-group {
            margin-bottom: 25px;
            text-align: left;
        }
        label {
            display: block;
            margin-bottom: 8px;
            font-weight: 600;
            color: #4a5568;
            font-size: 14px;
        }
        textarea {
            width: 100%;
            padding: 14px 16px;
            font-size: 16px;
            border: 2px solid #e2e8f0;
            border-radius: 8px;
            box-sizing: border-box;
            transition: all 0.3s ease;
            outline: none;
            background-color: #f8fafc;
            font-family: inherit;
            resize: none;
            min-height: 52px;
            overflow-y: hidden;
            line-height: 1.5;
        }
        textarea:focus {
            border-color: var(--primary-color);
            background-color: #fff;
            box-shadow: 0 0 0 3px rgba(74, 144, 226, 0.1);
        }
        button {
            background-color: var(--primary-color);
            color: white;
            border: none;
            padding: 14px 30px;
            font-size: 16px;
            font-weight: 600;
            border-radius: 8px;
            cursor: pointer;
            transition: all 0.2s ease;
            width: 100%;
            box-shadow: 0 4px 6px rgba(74, 144, 226, 0.2);
        }
        button:hover {
            background-color: var(--primary-hover);
            transform: translateY(-1px);
            box-shadow: 0 6px 8px rgba(74, 144, 226, 0.3);
        }
        button:active {
            transform: translateY(0);
            box-shadow: 0 2px 4px rgba(74, 144, 226, 0.2);
        }
        button:disabled {
            background-color: #cbd5e0;
            cursor: not-allowed;
            transform: none;
            box-shadow: none;
        }
        .download-btn {
            background-color: #48bb78;
            margin-top: 15px;
            display: none; /* Hidden by default */
            box-shadow: 0 4px 6px rgba(72, 187, 120, 0.2);
        }
        .download-btn:hover {
            background-color: #38a169;
            box-shadow: 0 6px 8px rgba(72, 187, 120, 0.3);
        }
        .download-btn:active {
            box-shadow: 0 2px 4px rgba(72, 187, 120, 0.2);
        }
        #result {
            margin-top: 30px;
            min-height: 60px;
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;
        }
        img {
            max-width: 100%;
            border-radius: 8px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
            animation: fadeIn 0.6s cubic-bezier(0.22, 1, 0.36, 1);
        }
        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(10px) scale(0.98); }
            to { opacity: 1; transform: translateY(0) scale(1); }
        }
        .loading {
            display: inline-block;
            width: 30px;
            height: 30px;
            border: 3px solid #f3f3f3;
            border-top: 3px solid var(--primary-color);
            border-radius: 50%;
            animation: spin 1s linear infinite;
        }
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
        .error-message {
            color: #e53e3e;
            background: #fff5f5;
            padding: 12px 16px;
            border-radius: 8px;
            font-size: 14px;
            border: 1px solid #fed7d7;
            width: 100%;
            box-sizing: border-box;
        }
        .status-text {
            color: #718096;
            font-size: 14px;
            margin-top: 10px;
        }
    </style>
</head>
<body>
<div class="container">
    <h2>Z-Image-Turbo WebUI</h2>
    <div class="input-group">
        <label for="prompt">Prompt 提示词</label>
        <textarea id="prompt" placeholder="输入提示词,例如:a cat in the snow" rows="1"></textarea>
    </div>
    <button id="generateBtn" onclick="generate()">生成图片</button>
    <button id="downloadBtn" class="download-btn" onclick="downloadImage()">下载图片</button>
    <div id="result"></div>
</div>
<script>
// Auto-resize textarea
const promptInput = document.getElementById("prompt");
promptInput.addEventListener("input", function(){
    this.style.height = "auto";
    this.style.height = this.scrollHeight + "px";
});

async function generate(){
    const resultDiv = document.getElementById("result");
    const btn = document.getElementById("generateBtn");
    const downloadBtn = document.getElementById("downloadBtn");
    const prompt = promptInput.value.trim();
    if(!prompt){
        // Shake animation for empty input
        promptInput.style.borderColor = "#e53e3e";
        promptInput.focus();
        setTimeout(()=>{ promptInput.style.borderColor = ""; }, 2000);
        return;
    }
    // UI Loading State
    btn. = ;
    downloadBtn.. = ; 
    btn. = ;
    resultDiv. = ; 

     formData =  ();
    formData.(, prompt);
    {
         resp =  (, {
            : ,
            : formData,
        });
        (!resp.){
              ();
        }
         data =  resp.();
        (data.){
            resultDiv. = ;
            downloadBtn.. = ; 
        }{
              ();
        }
    }(error){
        .(error);
        resultDiv. = ;
    }{
        btn. = ;
        btn. = ;
    }
}

 (){
     img = .();
    (img){
         a = .();
        a. = img.;
        a. = ;
        ..(a);
        a.();
        ..(a);
    }
}


promptInput.(, (){
    (event. ===  && !event.){
        event.();
        ();
    }
});
</script>
</body>
</html>

镜像构建与运行

1. 构建 Dockerfile

将上述两个文件放在与 Dockerfile 同一目录下。

Dockerfile 内容:

# 1. 基础镜像:改用 CUDA 12.4 (目前 PyTorch 支持最好的高版本)
# 即使物理机驱动是 CUDA 13,容器内用 CUDA 12.4 也是完全兼容的
FROM nvidia/cuda:13.0.1-runtime-ubuntu22.04

# 2. 环境变量设置
ENV DEBIAN_FRONTEND=noninteractive \
LANG=C.UTF-8 \
LC_ALL=C.UTF-8 \
PYTHONUNBUFFERED=1 \
# 显存优化参数
PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True \
# 设置默认模型路径,方便 Python 代码读取
MODEL_PATH=/data/models/Z-Image-Turbo

# 3. 安装系统依赖
# 增加了 git (pip 安装 git+... 需要) 和 curl
RUN apt-get update && apt-get install -y --no-install-recommends \
    python3 python3-pip python3-venv \
    git build-essential wget curl ca-certificates \
    libgl1 libglib2.0-0 libsm6 libxrender1 libxext6 \
&& rm -rf /var/lib/apt/lists/*

# 4. 升级 pip
RUN python3 -m pip install --upgrade pip
WORKDIR /workspace

# 5. 安装 PyTorch (CUDA 13 版本)
# 这里使用了 cu130 的源,确保下载到支持 GPU 的版本
RUN pip install --no-cache-dir torch torchvision --index-url https://download.pytorch.org/whl/cu130

# 6. 安装 Diffusers 和相关 AI 依赖
# 补充了 sentencepiece 和 protobuf (Transformers 必须)
RUN pip install --no-cache-dir git+https://github.com/huggingface/diffusers.git
RUN pip install --no-cache-dir transformers accelerate safetensors modelscope sentencepiece protobuf

# 7. 安装 Web 服务依赖
RUN pip install --no-cache-dir fastapi "uvicorn[standard]" pillow aiofiles python-multipart

# 8. 复制代码文件
COPY zimage_server.py /workspace/zimage_server.py
# 如果你有 index.html 也复制进去,没有则注释掉
COPY index.html /workspace/index.html

# 9. 暴露端口
EXPOSE 8000

# 10. 启动命令
# 确保 host 是 0.0.0.0 才能被外部访问
CMD ["uvicorn", "zimage_server:app", "--host", "0.0.0.0", "--port", "8000"]

2. 构建镜像

docker build -t zimage-server:v1 .

3. 运行容器

使用以下命令运行。请根据实际路径修改挂载点。

docker run --gpus all -d \
  -p 8000:8000 \
  -v /data/models/Z-Image-Turbo:/data/models/Z-Image-Turbo \
  -v ./index.html:/workspace/index.html:ro \
  -v ./zimage_server.py:/workspace/zimage_server.py:ro \
  --name zimage-container \
  zimage-server:v1

4. 验证运行状态

查看日志确认模型加载成功:

docker logs -f zimage-container

使用 Web 界面生图

在浏览器访问 http://服务器 IP:8000,输入提示词即可生成图片。

示例提示词: 一张融合'写实质感 + 二次元画风 + 高级 CG 渲染'的《鬼灭之刃》主题海报。主体是一位站在画面中央的灶门炭治郎,保持原有动漫面部特征与配色,但皮肤、眼睛、发丝与纹理采用写实级 CG 材质表现。角色手持日轮刀,刀刃释放淡蓝色'水之呼吸'CG 能量特效,能量呈流体状发光纹路,带有轻微粒子散射效果。他脚下是一块从雾气弥漫的浅水水面中浮出的深色湿润板岩,倒影清晰、略带二次元柔光边缘。光照与氛围(写实光影 + 动漫色调):金黄清晨体积光穿透森林树叶倾泻而下,形成真实物理感十足的体积雾与丁达尔效应,同时保留二次元式干净、高对比的光影边缘。斑驳的光斑落在炭治郎的脸部、刀刃与衣褶上,使写实材质与动漫色块互相融合。刀刃能量在水面上形成微光焦散 Caustics,与周围冷色雾气形成强烈视觉对比,制造史诗感。细节与材质(写实纹理 × 二次元线条):写实但带柔化处理的角色皮肤、精致的眼部渲染、半写实发丝质感。额头伤痕、耳饰与日轮刀纹路清晰,既保留原动画设计,又加入微微的金属反射与磨损细节。服装布料带有真实褶皱纹理,但边缘保留柔和的二次元描线。板岩湿润且带有微苔纹理,水面拥有真实反射与轻微折射,同时保持略微卡通化的干净色彩。背景灰烬微粒与落花片呈 CG 粒子效果,略带景深虚化。技术规格(CG 渲染 + 动漫视觉):采用虚幻引擎 5 超写实 CG 渲染风格混合高饱和、干净色块的二次元调色。8K 画质,面部与刀刃 Logo 区域超高清对焦。电影级光线追踪、漫反射 + 高光双层材质处理。动漫式色彩分级(高对比、清晰色层)与写实 CG 高动态范围光照融合。整体呈现电影海报级质感、CG 角色精度和动漫角色辨识度。

disabled
true
style
display
"none"
// Hide download button during generation
innerHTML
'<span></span> 生成中...'
innerHTML
""
// Clear previous result
const
new
FormData
append
"prompt"
try
let
await
fetch
"http://IP:8000/api/generate"
method
"POST"
body
if
ok
throw
new
Error
`HTTP error! status: ${resp.status}`
let
await
json
if
image
innerHTML
`<img src="data:image/png;base64,${data.image}" alt="Generated Image" />`
style
display
"block"
// Show download button
else
throw
new
Error
"No image data received"
catch
console
error
innerHTML
`<div>生成失败:${error.message}</div>`
finally
disabled
false
textContent
"生成图片"
function
downloadImage
const
document
querySelector
"#result img"
if
const
document
createElement
"a"
href
src
download
`z-image-${Date.now()}.png`
document
body
appendChild
click
document
body
removeChild
// Allow Enter key to submit (Shift+Enter for new line)
addEventListener
"keydown"
function
event
if
key
"Enter"
shiftKey
preventDefault
generate