InternLM / InternLM-XComposer

InternLM-XComposer2 is a groundbreaking vision-language large model (VLLM) excelling in free-form text-image composition and comprehension.
1.91k stars 120 forks source link

多轮多模态对话 #300

Open XKCUW opened 2 months ago

XKCUW commented 2 months ago

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

XKCUW commented 2 months ago

please

yuhangzang commented 2 months ago

Can u post your prompt format for us to check?

XKCUW commented 2 months ago

首轮对话 次轮对话

XKCUW commented 2 months ago

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

XKCUW commented 2 months ago

附加错误截图 image

zodiacg commented 2 months ago

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

ybshaw commented 1 month ago

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

irexyc commented 1 month ago

@zodiacg

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

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

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

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

zodiacg commented 1 month ago

@zodiacg

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

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

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

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

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

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

irexyc commented 1 month ago

@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 commented 1 month ago

@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中对应的代码。事实上没往下几行就有贴主报的错误,所以我做出了上面的推测。