Skip to content

feature: support gemini multimodal output #2197

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 32 commits into
base: main
Choose a base branch
from

Conversation

Laisky
Copy link
Contributor

@Laisky Laisky commented Mar 17, 2025

功能

支持 gemini multi-modal 输出,简而言之就是可以输出文字和图片

顺手也更新了一下 groq 和 replicate 的模型列表和价格。

分歧越来越大,越来越难合并了,可以使用 https://github.com/Laisky/one-api

自测

CleanShot 2025-03-17 at 09 55 54@2x

- Update pricing ratios and calculations for AI models in the billing system.
- Introduce new constants and enhance error handling for audio token rates.
- Comment out outdated pricing entries and include additional models in calculations.
@ArcaneWhispers
Copy link

ArcaneWhispers commented Mar 20, 2025

流式输出方式有问题,无法返回图片,只返回文字。我使用的你的 https://github.com/Laisky/one-api 这里的源码。非流格式是正常的。

data: {"id":"chatcmpl-a3783a2bb1a44be5a833beeacbe51e22","object":"chat.completion.chunk","created":1742465564,"model":"gemini","choices":[{"index":0,"delta":{"role":"assistant","content":"好的"}}]}

data: {"id":"chatcmpl-b0c3b719fa5a41c1bf36f85447107d37","object":"chat.completion.chunk","created":1742465564,"model":"gemini","choices":[{"index":0,"delta":{"role":"assistant","content":",请看这只站立在草地上的哈士奇:\n\n"}}]}

data: [DONE]

@Laisky
Copy link
Contributor Author

Laisky commented Mar 20, 2025

@ArcaneWhispers 建议换用 https://github.com/Laisky/one-api 已经经过测试是可用的

两边代码差距越来越大了,这边几个月几年都合不进去,PR 难免会漏东西。

@Laisky
Copy link
Contributor Author

Laisky commented Mar 20, 2025

刚才我把我那边 one-api 的最新代码全部合过来了。

@ArcaneWhispers
Copy link

@ArcaneWhispers 建议换用 https://github.com/Laisky/one-api 已经经过测试是可用的

两边代码差距越来越大了,这边几个月几年都合不进去,PR 难免会漏东西。

我用的就是你那边的代码,奇怪。

@Laisky
Copy link
Contributor Author

Laisky commented Mar 20, 2025

@ArcaneWhispers 建议换用 https://github.com/Laisky/one-api 已经经过测试是可用的
两边代码差距越来越大了,这边几个月几年都合不进去,PR 难免会漏东西。

我用的就是你那边的代码,奇怪。

拉下最新镜像试试,你说的这个问题出现过,但是前几天就修了。

@Laisky
Copy link
Contributor Author

Laisky commented Mar 20, 2025

@ArcaneWhispers 我盲猜是缓存不够导致的,返回的图片超过 1MB 就会这样。我刚把缓存改成 10MB 推了一版,镜像估计要等 3-5 分钟。晚上吃完饭我再测测。

这问题在我这不是必现,我画了 4-5 次才出现了一次。

@ArcaneWhispers
Copy link

@ArcaneWhispers 我盲猜是缓存不够导致的,返回的图片超过 1MB 就会这样。我刚把缓存改成 10MB 推了一版,镜像估计要等 3-5 分钟。晚上吃完饭我再测测。

这问题在我这不是必现,我画了 4-5 次才出现了一次。

感谢大佬,可以了 👍🏻。

可能我之前的提示词要求绘制3d效果图 比较大,果然将buffer设置大点 就可以。这里如果根据ContentLength大小动态设置大小是否更好一些。

@Laisky
Copy link
Contributor Author

Laisky commented Mar 20, 2025

@ArcaneWhispers 我看了下,返回的 header 里貌似没有 content-length

@xuhua912
Copy link

xuhua912 commented Apr 1, 2025

@Laisky 使用gemini-2.0-flash-exp-image-generation编辑图片,接口格式好像不太匹配,参考Google官网的接口文档:
image
下面是我自己的请求,用的ppcelery/one-api:arm64-latest镜像
image

@Laisky
Copy link
Contributor Author

Laisky commented Apr 1, 2025

@xuhua912 One-api 这个项目的意义,就在于对外提供统一的 OpenAI API 格式,所以你要使用 OpenAI 的 Completion API 格式来请求。

@xuhua912
Copy link

xuhua912 commented Apr 1, 2025

@xuhua912 One-api 这个项目的意义,就在于对外提供统一的 OpenAI API 格式,所以你要使用 OpenAI 的 Completion API 格式来请求。

谢谢,我现在不知道编辑图片怎么请求,有OpenAI 的 Completion API 格式来编辑图片的请求参考吗,issue里面只看到了生成图片的

@Laisky
Copy link
Contributor Author

Laisky commented Apr 1, 2025

@xuhua912 和 vision 一样,把图片放在历史消息里发送就行了,最好用 base64

https://platform.openai.com/docs/guides/images?api-mode=chat

@xuhua912
Copy link

xuhua912 commented Apr 1, 2025

@xuhua912 和 vision 一样,把图片放在历史消息里发送就行了,最好用 base64

https://platform.openai.com/docs/guides/images?api-mode=chat

再次感谢,我使用OpenAI的格式,还有Gemeni官网格式,还有2者结合的格式,都失败的,需求很简单就是输入一张图片和一段文字,让接口按照文字要求修改图片,然后返回新的图片。

尝试的过程如下:
1、OpenAI格式

{
    "model":"gemini-2.0-flash-exp-image-generation",
    "messages": [
        {
            "role": "user",
            "content": [
                {
                    "type": "input_text",
                    "text": "鞋子中黑色改成灰色"
                },
                {
                    "type": "input_image",
                    "image_url": "https://img4.pconline.com.cn/pconline/images/product/20231114/15251789.jpg"
                }
            ]
        }
    ]
}

错误:

{
    "error": {
        "message": "* GenerateContentRequest.contents[0].parts: contents.parts must not be empty.\n (request id: 2025040114152143735520936330822)",
        "type": "",
        "param": "",
        "code": 400
    }
}

2、Gemini格式:

{
    "model":"gemini-2.0-flash-exp-image-generation",
    "contents": [
        {
            "parts": [
                {
                    "text": "鞋子中黑色改成灰色"
                },
                {
                    "inline_data": {
                        "mime_type": "image/png",
			            "data": "{IMG_BASE64}"
                    }
                }
            ]
        }
    ],
    "generationConfig": {"responseModalities": ["Text", "Image"]}
}

错误:

{
    "error": {
        "message": "field messages is required (request id: 2025040114195354154454362790594)",
        "type": "one_api_error",
        "param": "",
        "code": "invalid_text_request"
    }
}

3、二者结合的格式:

{
    "model":"gemini-2.0-flash-exp-image-generation",
    "messages": [
        {
            "role": "user",
		    "contents": [
		        {
		            "parts": [
		                {
		                    "text": "鞋子中黑色改成灰色"
		                },
		                {
		                    "inline_data": {
		                        "mime_type": "image/png",
			                    "data": "{IMG_BASE64}"
		                    }
		                }
		            ]
		        }
		    ],
		    "generationConfig": {"responseModalities": ["Text", "Image"]}
        }
    ]
}

错误:

{
    "error": {
        "message": "* GenerateContentRequest.contents[0].parts: contents.parts must not be empty.\n (request id: 2025040114210054259683843668900)",
        "type": "",
        "param": "",
        "code": 400
    }
}

4、另外还参考了其他issue把Gemini的版本修改为v1beta也不行:
参考链接:#1979

docker run --name laisky-one-api -d --restart always -p 4000:3000 -e TZ=Asia/Shanghai -e GEMINI_VERSION=v1beta -v /Users/xuhua/data/one-api:/data ppcelery/one-api:arm64-latest

@Laisky
Copy link
Contributor Author

Laisky commented Apr 1, 2025

@xuhua912 one-api 仅提供 openai 格式,你不要加非 openai 的东西。

你去找找 gpt vision 的例子,我这会儿在外面不方便发代码

@xuhua912
Copy link

xuhua912 commented Apr 1, 2025

@xuhua912 one-api 仅提供 openai 格式,你不要加非 openai 的东西。

你去找找 gpt vision 的例子,我这会儿在外面不方便发代码

我尝试的第一中就是OpenAI格式的(如我下面截图),能不能晚点提供一个完整的使用gemini-2.0-flash-exp-image-generation模型来编辑图片的例子,谢谢

image

@Laisky
Copy link
Contributor Author

Laisky commented Apr 1, 2025

@xuhua912 你照着 openai vision 的格式去请求就行了,你这个肯定不是 openai 的格式,openai 哪有 input_image 这种 type,而且 image_url 是一个 object,不是 string。

这个接口功能肯定没问题,一大群人都用了快一个月了。你认认真真的照着 openai 的格式去请求,不要自己改字段。

https://platform.openai.com/docs/guides/images?api-mode=chat&format=base64-encoded

你可以拿 openai vision 去调试,vision 能通 gemini 的重绘肯定能通,有问题你再找我。

如果 vision 都调不通就别找我了

@xuhua912
Copy link

xuhua912 commented Apr 1, 2025

@xuhua912 你照着 openai vision 的格式去请求就行了,你这个肯定不是 openai 的格式,openai 哪有 input_image 这种 type,而且 image_url 是一个 object,不是 string。

这个接口功能肯定没问题,一大群人都用了快一个月了。你认认真真的照着 openai 的格式去请求,不要自己改字段。

https://platform.openai.com/docs/guides/images?api-mode=chat&format=base64-encoded

你可以拿 openai vision 去调试,vision 能通 gemini 的重绘肯定能通,有问题你再找我。

如果 vision 都调不通就别找我了

大佬,首先表明态度,我是在认真提问题想解决问题,不是在找茬。
我现在用OpenAI的格式,同样格式使用gpt-4o-mini,能正常返回结果(完全参考你发的OpenAI官方的,只是图片地址和提示词换了),只是只能返回文字不能返回图片,在这个基础上只修改model字段为gemini-2.0-flash-exp-image-generation就又报错了,所以你说了其他人用了一个多月了,能否给一个实例,谢谢。
用gpt-4o-mini正常的
image
用gemini-2.0-flash-exp-image-generation报错的
image

在oneapi的渠道测试,2个都是连通的
image

@Laisky
Copy link
Contributor Author

Laisky commented Apr 1, 2025

@xuhua912 这是你第一次提供正确的请求体,前面发的都是错误的。但是你请求 gemeni 的时候把图片换 base64 试试,我怀疑 one-api 里可能没自动帮你转成 b64。

我今天在外面,用手机没法给你发代码。

@xuhua912
Copy link

xuhua912 commented Apr 1, 2025

@xuhua912 这是你第一次提供正确的请求体,前面发的都是错误的。但是你请求 gemeni 的时候把图片换 base64 试试,我怀疑 one-api 里可能没自动帮你转成 b64。

我今天在外面,用手机没法给你发代码。

用base64,看了下OpenAI官网,只有python和JS版本,curl版本还是给的url,但还是用base64丢进去试了下,报:

{
    "error": {
        "message": "token not found: record not found (request id: 2025040117191070800625941961797)",
        "type": "one_api_error"
    }
}

请求格式

{
    "model": "gemini-2.0-flash-exp-image-generation",
    "messages": [
      {
        "role": "user",
        "content": [
          {
            "type": "text",
            "text": "鞋子中黑色改成灰色"
          },
          {
            "type": "image_url",
            "image_url": {
                "url": "data:image/png;base64,SOWUNVtf2bYuytoPOQsvohr4H...............",
            },
        ]
      }
    ]
}

@Laisky
Copy link
Contributor Author

Laisky commented Apr 1, 2025

@xuhua912

我回家试了下,这请求没问题。

你报错 token not found 是因为 token 不存在,你 API KEY 肯定用错了。

{
    "model": "gemini-2.0-flash-exp-image-generation",
    "max_tokens": 2048,
    "stream": false,
    "top_p": 0.9,
    "temperature": 0.9,
    "messages": [
        {
            "role": "system",
            "content": "you are a AI assistant"
        },
        {
            "role": "user",
                "content": [
                    {
                        "type": "text",
                        "text": "add another fish"
                    },
                    {
                        "type": "image_url",
                        "image_url": {
                            "url": "data:image/png;base64,xxxxxxx"
                        }
                    }
                ]
        }
    ]
}

@Laisky
Copy link
Contributor Author

Laisky commented Apr 1, 2025

@xuhua912 顺带修了一个小 BUG。

你之前传 URL 不行是因为你这个图片的 content-type 不是 image/ 开头的,而是 application/ 开头的。我把这个限制去掉了。

3547d09

@xuhua912
Copy link

xuhua912 commented Apr 2, 2025

@xuhua912 顺带修了一个小 BUG。

你之前传 URL 不行是因为你这个图片的 content-type 不是 image/ 开头的,而是 application/ 开头的。我把这个限制去掉了。

3547d09

没有太理解您的意思,我在http请求头Content-Type是application/json, 在body的JSON里面是这样:

{
	"model": "gemini-2.0-flash-exp-image-generation",
	"messages": [{
		"role": "user",
		"content": [{
				"type": "text",
				"text": "鞋子中黑色改成灰色"
			},
			{
				"type": "image_url",
				"image_url": {
					"url": "data:image/png;base64,SOWUNVtf2bYuy...................."
				}
			}
		]
	}]
}

报错:

{
    "error": {
        "message": " (request id: 2025040214202898297088301997267)",
        "type": "upstream_error",
        "param": "400",
        "code": "bad_response_status_code"
    }
}

one-api的渠道配置截图:
image

@Laisky
Copy link
Contributor Author

Laisky commented Apr 2, 2025

@xuhua912 现在没问题了吧

@xuhua912
Copy link

xuhua912 commented Apr 3, 2025

@xuhua912 现在没问题了吧

还有问题,就是我昨天发的问题,这个接口有测试成功过吗,我是各种都试过了都不行

@Laisky
Copy link
Contributor Author

Laisky commented Apr 3, 2025

@xuhua912 我没试过 gemini(openai) 的,你换 gemini 吧,如果还出错的话把 one-api 服务器日志发出来看看是什么问题。

这接口从发布到现在每天都有人用,还没出过问题。

@xuhua912
Copy link

xuhua912 commented Apr 3, 2025

@xuhua912 我没试过 gemini(openai) 的,你换 gemini 吧,如果还出错的话把 one-api 服务器日志发出来看看是什么问题。

这接口从发布到现在每天都有人用,还没出过问题。

gemini的接口,我用了生成图片是OK的,但是传入图片重绘是不可用的,请问你说的每天都有人用,是用的生图还是重绘场景?
下面分别给了正常和报错的情况,请帮忙再看下

1、生图接口正常
image

2、重绘接口报错
image

@Laisky
Copy link
Contributor Author

Laisky commented Apr 3, 2025

@xuhua912 绘图和重绘每天都有人用,从未出过问题。

从你提供的错误提示来看,你似乎提供了一个错误的 base64 编码。

这种问题你完全没必要找我,错误代码里很清晰地告诉你了,Base64 decoding failed,你找我有什么用呢?你又没给我提供完整的 base64 编码,我能知道你编码是对的还是错的吗?

目前为止你提供的代码都是有各种各样的错误,建议你多找找自己的问题,不要上来就质疑服务端有问题,我们讨论了这么多天,没任何一个问题是服务端导致的。

再次给你证明,重绘功能是没问题的,建议你认真审阅自己的代码,认真调试

CleanShot 2025-04-03 at 17 06 54@2x

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants