LangChain4j + OpenAI:dall-e-3实现文生图功能

1,373 阅读3分钟

本篇文章将介绍LangChain4j框架集成的图片大模型,并接入OpenAI实现文字生成图片功能!

集成图片模型

模型提供商模型名称API接入示例
OpenAIDall·E (2/3)OpenAiImageModelOpenAiImageModelExamples
Azure OpenAIDall·E (2/3)AzureOpenAiImageModelAzureOpenAIDallEExample
GoogleImagenVertexAiImageModelVertexAiImageModelIT
CloudflareWorkers AIWorkersAiImageModelWorkersAiImageModelIT
Zhipu AIZhipu AIZhipuAiImageModelZhipuAiImageModelIT

关于图片大模型的知识网站:

Workers AI: developers.cloudflare.com/workers-ai/

Google Imagen:An article about image generation with Imagen

智普: www.zhipuai.cn// open.bigmodel.cn/

图片大模型实现原理

# 08. Spring AI 接入OpenAI实现文字生成图片功能 文章中介绍了关于大模型的一些技术原理。

ImageModel源码

/**
 * 文本生成图片模型对接API
 */
public interface ImageModel {
    /**
     * 根据提示词生成图片
     * @param prompt 提示词.
     * @return 根据提示词生成的图片对象.
     */
    Response<Image> generate(String prompt);

    /**
     * 根据提示词,生成n张图片,并不是所有的模型都支持
     *
     * @param prompt 提示词.
     * @param n 指定生成几张图片.
     * @return 返回生成图片的对象列表.
     * @throws IllegalArgumentException 如果操作不被支持,则会抛出异常.
     */
    default Response<List<Image>> generate(String prompt, int n) {
        throw new IllegalArgumentException("Operation is not supported");
    }

    /**
     * 根据存在的图片,根据提示词编辑该图片。
     *
     * @param image  需要编辑图像的对象.
     * @param prompt 编辑图像的提示词.
     * @return 生成图片的对象.
     */
    default Response<Image> edit(Image image, String prompt) {
        throw new IllegalArgumentException("Operation is not supported");
    }

    /**
     * 根据现有的图片,根据提示词以及根据给定另外一张图片的不同生成新的图片
     *
     * @param image  需要编辑的图片对象.
     * @param mask   mask图对象,mask图作用就是指定要编辑的区域,并画到原图上。
     * @param prompt 提示词.
     * @return 生成图片对象.
     */
    default Response<Image> edit(Image image, Image mask, String prompt) {
        throw new IllegalArgumentException("Operation is not supported");
    }
}

接入大模型对于图片的操作,仅支持文生图、图片编辑功能,对于后三个方法的功能并不是所有的模型都支持。具体看模型对接时是否实现了后三个方法。

类结构

classDiagram
ImageModel <|-- OpenAiImageModel
ImageModel <|-- AzureOpenAiImageModel
ImageModel <|-- ZhipuAiImageModel
ImageModel <|-- WorkersAiImageModel
ImageModel <|-- VertexAiImageModel
ImageModel: +generate(String prompt)
ImageModel: +generate(String prompt, int n) {}
ImageModel: +edit(Image image, String prompt) {}
ImageModel: +edit(Image image, Image mask, String prompt){}
class OpenAiImageModel{
-String modelName 模型的名称
-String size 生成图片的尺寸
-String quality 生成图片的质量,仅della3生效
-String style 生成图片的风格「生动或自然的」
-String user 请求用户唯一标识
-String responseFormat 响应的格式,url/b64_json
-int maxRetries 请求重试的次数
-OpenAiClient client 对接OpenAI Client
+generate(String prompt)
+generate(String prompt, int n)
}
class AzureOpenAiImageModel{
-OpenAIClient client 对接AzureOpenAi
-String deploymentName 模型名称
-ImageGenerationQuality quality 图片生成质量
-ImageSize size 图片生成尺寸
-String user 请求用户唯一标识
-ImageGenerationStyle style 生成图片风格
-ImageGenerationResponseFormat responseFormat;
+generate(String prompt)
}
class ZhipuAiImageModel{
-String model 模型名称
-String userId 请求用于唯一标识
-Integer maxRetries 重试次数
-ZhipuAiClient client
+generate(String prompt)
}
class WorkersAiImageModel{
-String accountId
-String modelName
-WorkersAiApi workerAiClient
+generate(String prompt)
+edit(Image image, String prompt)
+edit(Image image, Image mask, String prompt)
}

class VertexAiImageModel{
-Long seed 随机种子数 0 到 2^32-1
-String endpoint 请求base url
-MimeType mimeType 格式 image/png image/jpeg
-Integer compressionQuality 压缩质量
-String cloudStorageBucket 云存储,比如生成图片存储在oss上
-EndpointName endpointName **不知道啥意思,后续研究**
-String language
-Integer guidanceScale
-String negativePrompt
-ImageStyle sampleImageStyle 生成图片风格
-Integer sampleImageSize
-AspectRatio aspectRatio 图片比例 比如4:3/16:9
-PersonGeneration personGeneration
-Boolean addWatermark 是否添加水印
-int maxRetries 重试次数
-Boolean withPersisting 
-String modelName 模型名称
-Path tempDirectory 生成图片临时存储路径
-Boolean logRequests 记录请求日志
-Boolean logResponses 记录返回日志

+generate(String prompt)
+generate(String prompt,int n)
+edit(Image image, String prompt)
+edit(Image image, Image mask, String prompt)
}

LangChain4j集成5种图片大模型,其中图片大模型的能力参差不齐,从控制参数以及实现的功能上由强到弱;

VertexAiImageModel > WorkersAiImageModel > OpenAiImageModel > AzureOpenAiImageModel > ZhipuAiImageModel

但是具体模型的生成效果的优劣还的需要通过实际验证。从功能上看VertexAiImageModel完胜

接入 OpenAI 实现文生图

application.yml

spring:
  application:
    name: image-service

server:
  port: 8808

langchain4j:
  open-ai:
    image-model:
      base-url: xxx
      api-key: xxx

Service

package org.ivy.image.service;

import dev.langchain4j.data.image.Image;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.ImageContent;
import dev.langchain4j.data.message.TextContent;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.openai.OpenAiImageModel;
import dev.langchain4j.model.output.Response;
import org.springframework.stereotype.Service;

@Service
public class ImageService {

    private final OpenAiImageModel openAiImageModel;
    private final OpenAiChatModel openAiChatModel;

    public ImageService(OpenAiImageModel openAiImageModel, OpenAiChatModel openAiChatModel) {
        this.openAiImageModel = openAiImageModel;
        this.openAiChatModel = openAiChatModel;
    }

    public String generateImage(String prompt) {
        Response<Image> generate = openAiImageModel.generate(prompt);
        String url = generate.content().url().toString();
        return String.format("<img src='%s' alt='%s'>", url, prompt);
    }

    public String see(String prompt) {
        UserMessage userMessage = UserMessage.from(
                TextContent.from(prompt),
                ImageContent.from("https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png")
        );
        Response<AiMessage> generate = openAiChatModel.generate(userMessage);
        return generate.content().text();
    }
}

Controller

package org.ivy.image.controller;

import org.ivy.image.service.ImageService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ImageController {
    private final ImageService imageservice;

    public ImageController(ImageService imageservice) {
        this.imageservice = imageservice;
    }

    @GetMapping("/image")
    public String generateImage(@RequestParam(
            value = "prompt",
            defaultValue = "Donald Duck in New York, cartoon style")
                                String prompt) {
        return imageservice.generateImage(prompt);
    }

    @GetMapping("/see")
    public String see(@RequestParam(required = false,defaultValue = "What do you see?") String prompt) {
        return imageservice.see(prompt);
    }
}

测试

image.png

代码示例与总结

代码示例:image

主要介绍了LangChain4j框架支持的图片大模型,并对 ImageModel 提供能力进行说明,并将其实现子类的能力进行对比。不同图片大模型能力上存在一定的差异性。有些可以实现图片编辑能力,有些仅支持文字生成图片。

本文仅实现了文生图的能力,对于图片的编辑,由于其它模型没有token,没有办法去实践。