LLM系列 | 23:多模态大模型:浦语·灵笔InternLM-XComposer解读、实战和思考

  • 引言

  • ​简介

  • 模型解读

    • 模型架构

    • 训练

  • 实战

    • 环境准备

    • 本地实测

    • 服务部署

  • 总结

引言

谁念西风独自凉,萧萧黄叶闭疏窗,沉思往事立残阳。

                                                         Created by DALL·E 3

小伙伴们好,我是《小窗幽记机器学习》的小编:卖热干面的小女孩。今天这篇小作文主要介绍由上海人工智能实验室推出的多模态模型浦语·灵笔。本文先介绍浦语·灵笔的模型细节,再以实战方式结束本地部署浦语·灵笔模型并实测各种任务上的效果。如果有疑问或者想要和小编进一步交流,欢迎通过《小窗幽记机器学习》找到小编。

简介

浦语·灵笔模型是基于书生·浦语大语言模型研发的视觉-语言大模型,提供图文理解和创作能力:

  • 图文交错创作:  浦语·灵笔可以为用户打造图文并貌的文章,具体是提供文章生成和配图选择的功能。这一能力由以下步骤实现:

    1. 理解用户指令,创作符合要求的文章

    2. 智能分析文章,自动规划插图的理想位置,确定图像内容需求。

    3. 基于以文搜图服务,从图库中检索出对应图片。

  • 图文理解: 浦语·灵笔设计了高效的训练策略,为模型注入海量的多模态概念和知识数据,赋予其强大的图文理解和对话能力。

从公布的技术报告可以获悉InternLM-XComposer在公开评测数据集上的战绩:在多项视觉语言大模型的主流评测上均取得了最佳性能,包括MME Benchmark (英文评测)、 MMBench (英文评测)、Seed-Bench (英文评测)、 CCBench(中文评测)、MMBench-CN (中文评测)。

截至目前(2023年10月14日)官方开源2个版本的浦语·灵笔模型:

  • InternLM-XComposer-VL-7B :该模型是基于书生·浦语大语言模型的多模态预训练和多任务训练模型,在多种评测上表现出杰出性能, 例如:MME Benchmark, MMBench Seed-Bench, CCBench, MMBench-CN。该模型是base模型,即常说的基座模型。

  • InternLM-XComposer-7B:进一步对InternLM-XComposer-VL进行指令微调得到nternLM-XComposer。该微调模型可以用于创作图文并茂的文章,也支持多模态对话(目前支持图文对话,更具体是围绕给定图片的讨论,暂不支持指令编辑给定的图片)。

以下为小编体验演示:

AI科技爱科学

GitHub: 

https://github.com/InternLM/InternLM-XComposer

技术报告: 

https://arxiv.org/abs/2309.15112

模型解读

模型架构

InternLM-XComposer整体架构由3部分组成,包括视觉编码器、LLM-model (本文即InternLM) 和对齐模块(报告中称为Perceive Sampler,感知采样器)。

1. 视觉编码器:InternLMXComposer 中的视觉编码器采用 EVA-CLIP,这是标准 CLIP的改进版本,用mask图像的方式增强了模型的建模能力,能够更有效地捕捉输入图像的视觉细节。在该模块中,图像被调整为统一的 224×224 尺寸,然后以步长为14的方式切割成图块。这些图块作为输入token,再利用transformer中的自注意力机制,从而提取图像embeddings。

2. Perceive 采样器:InternLM-XComposer中的感知采样器其实是一种池化机制,旨在将图像embeddings从初始的257维度压缩为64。这些压缩优化后的embeddings随后与大型语言模型理解的知识进行对齐。仿照BLIP2的做法,InternLM-XComposer利用BERT-base中cross-attention层作为感知采样器。

3. 大型语言模型:InternLM-XComposer用InternLM 作为其基础大型语言模型。值得注意的是,InternLM 是一种功能强大的多语言模型,擅长英语和中文。具体是使用已经公开的 InternLM-Chat-7B 作为大型语言模型。

训练

InternLM-XComposer的训练过程分为 A 阶段和 B 阶段。A 阶段作为预训练阶段,利用大量数据训练基座模型。B阶段是监督微调,先做多任务训练,再做指令微调。在多任务训练后得到InternLM-XComposer-VL模型,在指令微调得到InternLM-XComposer模型。

1. Pre-training阶段:预训练基座视觉语言模型阶段利用了大量的图像-文本对(网络爬取)和交错的图像-文本数据。这些数据包括中英文两种语言的多模态数据。为了保持大型语言模型的语言能力,在 InternLM 预训练阶段使用的部分文本数据也在 InternLM-XComposer 的预训练阶段中使用。如Table 1 所示:

图像-文本对方面,使用了 11 亿张图像和 677 亿个文本token(其中506亿个英文文本token和171亿个中文文本token),包括公开数据集和从内部数据(从网站爬取收集),总共超过 1100 万个语义概念。内部数据集In-house Data有一个开放的子集:书生·万卷文本数据集。这个开源数据集,包含三个部分:纯文本格式数据集、文本-图像对数据集和视频数据集,可以从官网下载到,相关的数据说明也可以在对应论文上查阅。此外,还加入了约100亿个从InternLM 预训练数据集中抽样的文本token,以维持模型的语言能力。在训练过程中,所有预训练数据都经过了严格的清洗流程,以确保其质量和可靠性。

在预训练阶段,视觉编码器参数固定,主要对感知采样器和大型语言模型进行优化。感知采样器和大型语言模型的初始权重分别来自BLIP2和InternLM。由于大型语言模型天然缺乏对图像embeddings的理解,因此在多模态预训练框架内做优化有助于提高理解这些embeddings的能力。模型的训练目标集中在下一个token预测上,使用交叉熵损失作为损失函数。采用的优化算法是 AdamW,超参数设置如下:β1=0.9,β2=0.95,eps=1e-8。感知采样器和大型语言模型的最大学习速率分别设置为 2e-4 和 4e-5,采用余弦学习率衰减策略,最小学习率设置为1e-5。此外,在最初的 200 步中使用线性预热。训练过程一个batch size中约 1570 万个token,并进行 8000 次迭代。使用如此大的batch size有助于稳定训练,同时也有助于维持InternLM的固有能力。

2. 监督微调阶段:在预训练阶段,图像embeddings与文本表征对齐,使大型语言模型具有初步具备理解图像内容的能力。为进一步指导模型在恰当时机使用图像信息的能力,引入了各种视觉-语言任务。所以,整个监督微调阶段,其实由多任务训练和指令微调组成。

多任务训练。多任务训练数据集如Table 2 所示,这些任务包括场景理解(例如 COCO Caption,SUB)、位置理解(例如 Visual Spatial Reasoning 数据集)、光学字符识别OCR(例如 OCR-VQA)以及开放式回答(例如 VQAv2 ,GQA)等。

每个任务都被设计成会话交互形式,具体格式如下:

其中和 分别表示用户和机器人结束token。对于每张图像具有多个问题的QVA数据集,将其构造成多轮对话,问题随机排序,从而大大提高了 SFT 过程的效率。在这个阶段,所有问题都通过人工编写的提示引入,以增加任务的多样性。为了实现稳定且高效的微调,将大型语言模型的权重冻结,然后使用 Low-Rank Adaption(LoRA)架构进行模型微调。当然,在这个过程中,感知采样器也同时进行训练,只是学习率不同。LoRA 应用于注意力层的 query、value 和 key 以及前馈网络。实验发现较高的LoRA rank有助于赋予模型新能力;因此,将 LoRA rank和 alpha 参数都设置为 256。模型在10,000次迭代训练中使用全局batch size,值为256。LoRA 层和感知采样器的学习速率分别设置为 5e-5和 2e-5。

指令微调。为了进一步提升上述模型的指令跟随和交错的图像-文本组合能力,使用来自纯文本对话语料库和LLava-150k 的数据进行指令微调。此外,使用 LRV 数据集减轻幻觉。交错的图像-文本组合数据集的构建方法,可以查阅原始技术报告,这里略过。Batch size=256,并在1000 次迭代中使用较小的学习速率=1e-5。

实战

环境准备

安装 flash-attention:参考官方项目安装flash-attention:

pip3 install flash-attn --no-cache-dir  --no-build-isolation -i https://mirrors.cloud.tencent.com/pypi/simple

安装 rotaty

pip3 install "git+https://github.com/Dao-AILab/flash-attention.git#subdirectory=csrc/rotary" -i https://mirrors.cloud.tencent.com/pypi/simple

如果不安装,可能报错:

  File "/root/.cache/huggingface/modules/transformers_modules/internlm-xcomposer-7b/modeling_InternLM.py", line 5, in <module>
    import rotary_emb
ModuleNotFoundError: No module named 'rotary_emb'

注意,如果需要设置代理,请提前设置:

export HTTPS_PROXY=XXX
export HTTP_PROXY=XXXX

本地实测

取如下图片进行测试:

测试代码:

"""
CUDA_VISIBLE_DEVICES=7 python3 examples/example_chat.py
"""
import torch
from transformers import AutoModel, AutoTokenizer

torch.set_grad_enabled(False)

# init model and tokenizer
model_id = "/home/model_zoo/LLM/internlm/internlm-xcomposer-7b/"
model = AutoModel.from_pretrained(model_id, trust_remote_code=True).cuda().eval()
tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)
model.tokenizer = tokenizer

# example image
image = 'examples/images/baoguoma.jpeg'

# Single-Turn Pure-Text Dialogue
text = '请介绍下马保国'
response = model.generate(text)
print(f'User: {text}')
print(f'Bot: {response}')

# Single-Turn Text-Image Dialogue
text = '请问这张图片里面的人是谁?并介绍下他。'
image = 'examples/images/baoguoma.jpeg'
response = model.generate(text, image)
print(f'User: {text}')
print(f'Bot: {response}')

# Multi-Turn Text-Image Dialogue
# 1st turn
text = '图片里面的是谁?'
response, history = model.chat(text=text, image=image, history=None)
print(f'User: {text}')
print(f'Bot: {response}')

# 2nd turn
text = '他有哪些成就?'
response, history = model.chat(text=text, image=None, history=history)
print(f'User: {text}')
print(f'Bot: {response}')

# 3rd turn
text = '他是最伟大的物理学家吗?'
response, history = model.chat(text=text, image=None, history=history)
print(f'User: {text}')
print(f'Bot: {response}')

输出结果:

User: 请介绍下马保国
Bot: 马保国,男,汉族,1952年出生于河北省邯郸市大名县,中国武术家。

2015年11月30日,马保国在一场业余搏击比赛中,被业余选手王庆民连续三拳打倒在地,随后倒地不起,被送往医院后抢救无效去世。


User: 请问这张图片里面的人是谁?并介绍下他。
Bot: 这张图片里面的人是一位男子,他戴着墨镜,面带微笑,看起来心情不错。男子名叫郭德纲,是中国著名的相声演员和主持人。

User: 图片里面的是谁?
Bot: 图片里面的是郭德纲。

User: 他有哪些成就?
Bot: 郭德纲是中国相声演员、主持人、影视演员。

User: 他是最伟大的物理学家吗?
Bot: 对不起,郭德纲并不是物理学家。

换成蔡某某的照片:

重新测试,输出结果如下:

User: 请介绍下蔡徐坤
Bot: 蔡徐坤(Cai Xukun),1998年8月2日出生于浙江省温州市,中国内地流行乐男歌手、影视演员。

2012年,参加选秀节目《向上吧!少年》进入全国300强
。2013年,参加浙江卫视歌唱选秀节目《中国好声音第二季》,最终获得周杰伦组亚军、全国总决赛季军
。2018年4月6日,发行个人首支原创单曲《I Wanna Get Love》
;5月2日,发行原创单曲《Wait Wait Wait》
;8月2日,发行原创单曲《Hard To Get》
;12月21日,发行原创单曲《Pull Up》
。2019年1月1日,发行原创单曲《YOUNG》
;2月14日,发行原创单曲《情人》
;4月6日,发行原创单曲《重生》
;7月6日,发行原创
User: 请问这张图片里面的人是谁?并介绍下他。
Bot: 这张图片里的人是蔡徐坤。蔡徐坤是一位中国男歌手和演员,他在2018年通过选秀节目《偶像练习生》出道,成为NINE PERCENT成员之一。

User: 图片里面的是谁?
Bot: 蔡徐坤

User: 他有哪些成就?
Bot: 蔡徐坤是中国内地流行乐男歌手、音乐制作人、影视演员。

User: 他是最伟大的篮球运动员吗?
Bot: 对不起,我无法回答这个问题。

User: 描述下这张图片?
Bot: 这是一张蔡徐坤的照片,他正在打篮球。

服务部署

如果服务器因为网络原因只能使用本地模型,或者个人已经其他下载好模型,想要直接指定模型路径,那么需要进行几处修改。

  1. modeling_vit.py将原来的:

url = "https://storage.googleapis.com/sfr-vision-language-research/LAVIS/models/BLIP2/eva_vit_g.pth"
    cached_file = download_cached_file(url, check_hash=False, progress=True)

改为:

# 预先下载好 "https://storage.googleapis.com/sfr-vision-language-research/LAVIS/models/BLIP2/eva_vit_g.pth" 文件,然后存在机器上。

cached_file = "/home/model_zoo/LLM/internlm/internlm-xcomposer-7b/eva_vit_g.pth"
  1. modeling_InternLM_XComposer.py:将原来的

encoder_config = BertConfig.from_pretrained("bert-base-uncased")

改为:

# 预先下载https://huggingface.co/bert-base-uncased/tree/main的模型存于 /home/model_zoo/LLM/bert-base-uncased
local_model_path = "/home/model_zoo/LLM/bert-base-uncased"  # "bert-base-uncased"
encoder_config = BertConfig.from_pretrained(local_model_path)

将原来的:

Qformer = BertLMHeadModel.from_pretrained("bert-base-uncased", config=encoder_config)

改为:

local_model_path = "/home/model_zoo/LLM/bert-base-uncased" 
Qformer = BertLMHeadModel.from_pretrained(local_model_path, config=encoder_config)

启动服务:

CUDA_VISIBLE_DEVICES=7 python3 examples/web_demo.py

图文交错创作功能测试:

其中文章生成的配图来自调用内部以文搜图模块,并非通过图片生成的方式。但是,以文搜图的图库和背后的逻辑并没有说明,目前只给出一个调用接口https://lingbi.openxlab.org.cn/image/similar,且caption字符串最多54个字符。

图文理解测试:

总结

虽然技术层面没有太多创新,但是图文交叉的产品应用形态,还是值得肯定和借鉴的。如果可以进一步支持文章配图生成,直接解决配图版权问题,在体验层面会有更多惊喜。其实,小编在每篇小作文开头的配图都是生成的,比如今天小作文开头诗句配图就是通过DALL·E 3直接生成的。至于图文理解方面效果还行,但是对于近期知识和图中图标等一些局部元素的理解不足。后续需要考虑如何增量的方式融入新知识或者使用类似LORA的方式挂载外部知识。

此外,在使用过程中发现,ORC效果很差,但是技术报告里面声称,在微调阶段使用了OCR数据:OCR-VQA,但是在实际使用的时候,为啥OCR能力如此差?同样有待后续提高。

猜你喜欢

转载自blog.csdn.net/ljp1919/article/details/134085575
今日推荐