Skip to content
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

多轮多模态对话 #300

Open
XKCUW opened this issue Apr 29, 2024 · 11 comments
Open

多轮多模态对话 #300

XKCUW opened this issue Apr 29, 2024 · 11 comments
Assignees

Comments

@XKCUW
Copy link

XKCUW commented Apr 29, 2024

想问一下,xcomposer2是否支持多轮带图问答?
也就是 每一轮都是<图+文>的输入,我在构建对话后,一直提示ValueError: Invalid prompt format. 似乎按照开源代码无法进行多轮<图+文>对话
plus:我想使用这种方式是因为首轮想提供给模型一个标准引导(one-shot),然后再第二轮再进行提问

@XKCUW
Copy link
Author

XKCUW commented Apr 29, 2024

please

@yuhangzang
Copy link
Collaborator

Can u post your prompt format for us to check?

@XKCUW
Copy link
Author

XKCUW commented Apr 29, 2024

首轮对话
次轮对话

@XKCUW
Copy link
Author

XKCUW commented Apr 29, 2024

首轮对话我获得response、history
然后我讲history传入第二次对话,就会发生错误
其中 auditVLMBot就是通过官方初始化的模型类(我封装了一下)
image

@XKCUW
Copy link
Author

XKCUW commented Apr 29, 2024

附加错误截图
image

@zodiacg
Copy link

zodiacg commented Apr 30, 2024

随便猜的,你试试:
大模型实际上不存在“多轮”对话,第一轮之后模型没有保存着中间状态等着你输入下一句。每次添加一轮对话模型都会先计算前面的对话历史,然后继续输出。
因此在处理“第二轮”对话时,应当确保images中的图像数与历史对话+当轮问题中的数量等同。换句话说你依然需要process已经对话过的图像并且放在images里

@ybshaw
Copy link

ybshaw commented May 6, 2024

附加错误截图 image
请问下你这个多模态是7B版的吗,还是量化后的,如果是7B的话GPU是什么配置呢

@irexyc
Copy link

irexyc commented May 15, 2024

@zodiacg

第一轮之后模型没有保存着中间状态等着你输入下一句。每次添加一轮对话模型都会先计算前面的对话历史,然后继续输出。

在接收新一轮的对话时,历史对话的kvcache完全可以保留, 这样就不用重复计算了,这是推理框架决定的,而不是大模型都这样。

关键的问题在于,多轮多图时,prompt该怎么拼。如果图片token的位置拼在当前轮user的prompt当中,是可以做到不重复计算,但是如果要求拼在开头,那么就会破坏历史,历史的kvcache也就无效了。

很多模型做不到“图文交错”对话。很多模型给的多图多轮对话的例子,都只是在最开始输入了多图。如果不用实例代码给的接口,直接手动拼embedding,然后调transformers的接口,会发现效果真的不怎么行。

@zodiacg
Copy link

zodiacg commented May 15, 2024

@zodiacg

第一轮之后模型没有保存着中间状态等着你输入下一句。每次添加一轮对话模型都会先计算前面的对话历史,然后继续输出。

在接收新一轮的对话时,历史对话的kvcache完全可以保留, 这样就不用重复计算了,这是推理框架决定的,而不是大模型都这样。

关键的问题在于,多轮多图时,prompt该怎么拼。如果图片token的位置拼在当前轮user的prompt当中,是可以做到不重复计算,但是如果要求拼在开头,那么就会破坏历史,历史的kvcache也就无效了。

很多模型做不到“图文交错”对话。很多模型给的多图多轮对话的例子,都只是在最开始输入了多图。如果不用实例代码给的接口,直接手动拼embedding,然后调transformers的接口,会发现效果真的不怎么行。

我指的就是prompt怎么拼。如果我没记错,目前所有大模型提供的api接口时都是要求多轮提交时自带对话历史,并且占用token数,不存在服务器保留session只提交下一轮对话的情况。prefill比输出便宜当然是因为kvcache没错,但这跟你每次提交依然要把所有对话历史拼进去没有冲突。

images放在一起不等于拼在了开头,internlm-xcomposer恰恰就是做到了图文交错,它会把图像编码后放在文本中出现的位置。所以拼接新一轮次的对话时,必须保留历史图像,否则images与的数量就会不对应。如果把历史的图像不再输入才会破坏输入结构导致kvcache失效

@irexyc
Copy link

irexyc commented May 15, 2024

@zodiacg

我指的就是prompt怎么拼。如果我没记错,目前所有大模型提供的api接口时都是要求多轮提交时自带对话历史,并且占用token数,不存在服务器保留session只提交下一轮对话的情况。prefill比输出便宜当然是因为kvcache没错,但这跟你每次提交依然要把所有对话历史拼进去没有冲突。

lmdeploy 就支持interactive的对话,即获取下一轮的输入后可以不对历史的input做prefill。

images放在一起不等于拼在了开头,internlm-xcomposer恰恰就是做到了图文交错,它会把图像编码后放在文本中出现的位置。所以拼接新一轮次的对话时,必须保留历史图像,否则images与的数量就会不对应。如果把历史的图像不再输入才会破坏输入结构导致kvcache失效

这个你可能没get到我的点。图文交错是指每一轮的prompt都可以有image信息。而不是指图片的token放到user中的位置。类似deepspeed-visualchat那个图1。xcomposer我好像没看到说支持 'interleaved text-and-image conversations'

举个例子:
对于这样的历史 <user>{image}{question1}</user> <assistant>{answer1},如果下一轮有图片,
理想的prompt应该是<user>{image}{question1}</user> <assistant>{answer1}<user>{image}{question2}</user><assistant>
但是按照某些模型的demo会拼成这样 <user>{image}{image}{question1}</user> <assistant>{answer1}<user>{question2}</user><assistant>

前者每一轮的输入不会改变历史prompt结构,kvcache可以复用,就看框架是否支持。后者会破坏历史prompt的结构(因为后一轮的图片放到第一轮了),kvcache没办法复用。

@zodiacg
Copy link

zodiacg commented May 15, 2024

@zodiacg

lmdeploy 就支持interactive的对话,即获取下一轮的输入后可以不对历史的input做prefill。

那倒是非常实用

举个例子: 对于这样的历史 <user>{image}{question1}</user> <assistant>{answer1},如果下一轮有图片, 理想的prompt应该是<user>{image}{question1}</user> <assistant>{answer1}<user>{image}{question2}</user><assistant>, 但是按照某些模型的demo会拼成这样 <user>{image}{image}{question1}</user> <assistant>{answer1}<user>{question2}</user><assistant>

前者每一轮的输入不会改变历史prompt结构,kvcache可以复用,就看框架是否支持。后者会破坏历史prompt的结构(因为后一轮的图片放到第一轮了),kvcache没办法复用。

我非常get到你的点,可能是你没搞懂internlm-xcomposer2。

internlm-xcomposer2实际组织形式就是你所说的这种,图片位置由输入中的<ImageHere>token指出(抱歉上个回复忘了转义被吞了,可能你没注意到)。它只是把图像的具体路径或内容放在了统一的位置,这跟最终token的组织方式没有任何必然联系。

你可以任选一版xcomposer去看它的modeling_internlm_xcomposer2.py中对应的代码。事实上没往下几行就有贴主报的错误,所以我做出了上面的推测。

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

No branches or pull requests

6 participants