下面是GPT5.2的回答

这个问题你问得非常专业,而且刚好是很多人会混淆的点。
我直接给你结论 + 结构图 + 实战理解,一次说清楚。


一句话结论(先记住这个)

即梦生图 = 豆包生图的“专业图像模型产品线”
豆包生图 ≠ 豆包文本模型生图

换句话说:

  • 豆包生图,底层用的就是「即梦(Seedream)」
  • 即梦是豆包体系里“专门做图片生成”的那一支

体系结构图(最直观)

豆包大模型体系(Doubao)
│
├── 文本大模型(Text)
│   ├── doubao-lite-32k
│   ├── doubao-pro
│   └── ...
│
└── 图像大模型(Image / Multimodal)
    └── 即梦(Seedream)
        ├── doubao-seedream-4.0
        ├── doubao-seedream-4.5
        └── ...

👉 不存在一个“豆包文本模型直接生图”的模型
👉 所有“豆包生图”,本质都是在调 即梦(Seedream)


那为什么大家会说“豆包也能生图”?

因为有 三层“壳”,容易让人误解:

1️⃣ 产品层(App / 官网)

  • 豆包 App / Web 里点「生成图片」
  • 实际:后台调用即梦模型

2️⃣ 模型命名层

你看到的模型名是:

doubao-seedream-4-5-251128
  • doubao → 豆包体系
  • seedream → 即梦图像模型

3️⃣ API 接入层(Ark)

  • 同一个 Base URL
  • 同一个 API Key
  • 不同 endpoint

所以工程上看起来“都是豆包”,但能力是分开的。


即梦生图 vs 豆包文本模型(对照表)

维度 即梦生图(Seedream) 豆包文本模型
能力 图片生成 文本生成
输出 图片 文本
能否生图
接口 /images/generations /chat/completions
是否同一模型
是否同一体系

“豆包生图”在 API 里长什么样?

只要你看到这些,就一定是即梦:

{
  "model": "doubao-seedream-4-5-251128",
  "prompt": "...",
  "size": "2K"
}

即使你是在“豆包”控制台点的,也是它。


为什么要单独搞一个「即梦」?

从工程角度非常合理:

  • 图像模型 ≠ 文本模型
  • 架构 / 推理 / 成本 完全不同
  • 风控、版权、审美都需要独立策略

所以:

  • 豆包 = 总品牌
  • 即梦 = 图像专用模型线

实战建议(对你这种在写代码的人很重要)

✅ 正确姿势

  • 文本 → doubao-lite-32k
  • 图片 → doubao-seedream-4-5-251128

❌ 错误姿势

  • 指望文本模型生图
  • 指望即梦出文案

你现在其实已经用对了

你现在的代码、思路已经是 官方推荐的工程组合,只是在:

  • 参数边界(max_images)
  • 风控(IP/敏感词)

这两块踩了坑。


如果你愿意,我可以再帮你画一份:

  • 产品视角 vs API 视角 vs 模型视角 的对照表
  • 或直接帮你设计一个 “豆包文案 + 即梦配图”的营销素材生成服务架构

你是更关心 技术原理,还是 怎么把它用在业务里

下面是跑通的代码

import os
import time
from pathlib import Path
from typing import List, Optional, Union

import requests

BASE_URL = "https://ark.cn-beijing.volces.com/api/v3"
API_KEY = os.getenv("ARK_API_KEY")  # 请提前设置环境变量

if not API_KEY:
    raise RuntimeError("请先设置环境变量 ARK_API_KEY")


def generate_images(
    prompt: str,
    model: str = "doubao-seedream-4-5-251128",
    size: str = "2K",
    n: int = 1,  # 生成图片数量(组图)
    image: Optional[Union[str, List[str]]] = None,  # 单图或多图 URL
    watermark: bool = False,
    timeout: int = 60,
) -> dict:
    """
    即梦 / Doubao-Seedream-4.5 图片生成
    支持:文生图 / 单图图生图 / 多图图生图 / 组图
    """
    url = f"{BASE_URL}/images/generations"
    headers = {
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json",
    }

    payload = {
        "model": model,
        "prompt": prompt,
        "size": size,
        "n": n,
        "watermark": watermark,
    }

    # 图生图(单图或多图)
    if image is not None:
        payload["image"] = image

    resp = requests.post(url, headers=headers, json=payload, timeout=timeout)
    resp.raise_for_status()
    return resp.json()


def download_images(image_urls: List[str], out_dir: str = "outputs") -> List[Path]:
    out_path = Path(out_dir)
    out_path.mkdir(parents=True, exist_ok=True)

    saved_files = []
    for idx, url in enumerate(image_urls):
        filename = f"img_{int(time.time()*1000)}_{idx}.jpg"
        file_path = out_path / filename

        r = requests.get(url, timeout=60)
        r.raise_for_status()
        file_path.write_bytes(r.content)

        saved_files.append(file_path)

    return saved_files


if __name__ == "__main__":
    result = generate_images(
        prompt="赛博朋克风格的未来上海夜景,霓虹灯,高对比度,电影级光影,超清细节",
        n=4,  # 生成 4 张组图
        size="2K",
    )

    print("API 返回:", result)

    urls = [item["url"] for item in result["data"]]
    files = download_images(urls)

    print("已保存文件:")
    for f in files:
        print(f)

  

生成的结果:

在这里插入图片描述

批量生图

生成16张:每次生成4张,跑4轮

import os
import time
from pathlib import Path
from typing import List, Optional, Union

import requests

BASE_URL = "https://ark.cn-beijing.volces.com/api/v3"
API_KEY = os.getenv("ARK_API_KEY")  # 请提前设置环境变量

if not API_KEY:
    raise RuntimeError("请先设置环境变量 ARK_API_KEY")


def generate_images(
    prompt: str,
    model: str = "doubao-seedream-4-5-251128",
    size: str = "2K",
    n: int = 1,  # 普通多张(若网关支持)
    image: Optional[Union[str, List[str]]] = None,
    watermark: bool = False,
    timeout: int = 60,
    # 组图/连续生成相关
    sequential_image_generation: Optional[str] = None,  # "auto" / "enable" 等(以文档为准)
    max_images: Optional[int] = None,                   # 组图张数
) -> dict:
    url = f"{BASE_URL}/images/generations"
    headers = {
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json",
    }

    payload = {
        "model": model,
        "prompt": prompt,
        "size": size,
        "n": n,
        "watermark": watermark,
        "response_format": "url",
        "stream": False,
    }

    if image is not None:
        payload["image"] = image

    # ✅ 触发“组图输出(多图输出)”
    if sequential_image_generation is not None:
        payload["sequential_image_generation"] = sequential_image_generation
    if max_images is not None:
        payload["sequential_image_generation_options"] = {"max_images": max_images}

    resp = requests.post(url, headers=headers, json=payload, timeout=timeout)
    if resp.status_code != 200:
        print("❌ status =", resp.status_code)
        print("❌ response =", resp.text)   # 关键:看服务端具体报什么
        resp.raise_for_status()
    return resp.json()


def download_images(image_urls: List[str], out_dir: str = "outputs") -> List[Path]:
    out_path = Path(out_dir)
    out_path.mkdir(parents=True, exist_ok=True)

    saved_files = []

    for idx, url in enumerate(image_urls):
        print(f"⬇️  downloading [{idx + 1}/{len(image_urls)}]: {url}")

        filename = f"img_{int(time.time() * 1000)}_{idx}.jpg"
        file_path = out_path / filename

        r = requests.get(url, timeout=60)
        r.raise_for_status()
        file_path.write_bytes(r.content)

        saved_files.append(file_path)

    return saved_files

# def download_images(image_urls: List[str], out_dir: str = "outputs") -> List[Path]:
#     out_path = Path(out_dir)
#     out_path.mkdir(parents=True, exist_ok=True)

#     saved_files = []
#     for idx, url in enumerate(image_urls):
#         filename = f"img_{int(time.time()*1000)}_{idx}.jpg"
#         file_path = out_path / filename

#         r = requests.get(url, timeout=60)
#         r.raise_for_status()
#         file_path.write_bytes(r.content)

#         saved_files.append(file_path)

#     return saved_files
# if __name__ == "__main__":
#     result = generate_images(
#         #@prompt="生成一组4张连贯插画,表现同一城市街道在清晨、正午、黄昏、夜晚的变化,赛博朋克风格",
#         prompt="生成不同风格的奥特曼",
#         size="2K",
#         sequential_image_generation="auto",
#         max_images=4,
#     )

#     print("data_len =", len(result.get("data", [])))

#     urls = [item["url"] for item in result["data"]]
#     print("开始下载图片...")

#     files = download_images(urls, out_dir="outputs")

#     print("\n✅ 下载完成:")
#     for f in files:
#         print(f)


# if __name__ == "__main__":
#     result = generate_images(
#     prompt="生成一组共4张连贯插画,核心为同一庭院一角的四季变迁,以统一风格展现四季独特色彩、元素与氛围",
#     size="2K",
#     sequential_image_generation="auto",
#     max_images=4,
#     )
#     print("data_len =", len(result.get("data", [])))


  
if __name__ == "__main__":
    all_urls = []
    total = 16
    batch = 4  # 建议先用 4(你已验证成功)

    rounds = (total + batch - 1) // batch

    for r in range(rounds):
        print(f"\n=== Round {r+1}/{rounds} ===")
        result = generate_images(
            prompt="生成不同风格的原创日式特摄科幻英雄,银色装甲红色发光眼睛,胸口能量核心,每张风格不同,高清细节",
            size="2K",
            sequential_image_generation="auto",
            max_images=batch,
            # n 保持默认 1 就行,避免有的网关对 n+sequential 组合敏感
            n=1,
        )

        data = result.get("data", [])
        print("data_len =", len(data))
        urls = [item["url"] for item in data if "url" in item]
        all_urls.extend(urls)

    print(f"\n✅ 总共拿到 {len(all_urls)} 张,开始下载...")
    files = download_images(all_urls, out_dir="outputs")

    print("\n✅ 下载完成:")
    for f in files:
        print(f)

后记

2026年2月5日周四于上海。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐