1_多模态介绍
多模态是指表达或感知事物的方式,例如视觉、听觉、嗅觉。
对应的信息传递媒介可以是不同类型的数据,如文本、图像、声音、视频等。
多模态就是从多个模态表达或感知事物。
大部分情况与大模型交互都是基于普通文本输入,只有需要解析图片等其他类型数据时才会用到多模态模型。
deepseek
、qwen-plus
等模型都是纯文本模型,在 Ollama 和百炼平台,也能找到很多多模态模型。
以 Ollama 为例,在搜索时点击 Vision,就能找到支持图像识别的模型:
在阿里云百炼平台也一样:
阿里云百炼平台的 qwen-omni
模型是支持文本、图像、音频、视频输入的全模态模型,还能支持语音合成功能,非常强大。
2_定义模型
创建用于多模态对话的 ChatClient:
@Bean
public ChatClient chatClient(OpenAiChatModel model, ChatMemory chatMemory) {
return ChatClient.builder(model)
.defaultOptions(ChatOptions.builder().model("qwen-omni-turbo").build())
.defaultSystem("你是我的助手,名字叫小微")
.defaultAdvisors(
new SimpleLoggerAdvisor(),
MessageChatMemoryAdvisor.builder(chatMemory).build()
).build();
}
application.yaml
配置文件中 spring.ai.openai.chat.options.model
属性已经指定了 qwen-plus
为默认的 Chat 模型(由于其他业务使用的原因,不能改变)。
也就是说会产生冲突,因此创建 Bean 时使用 defaultOptions
方法指定了模型名称。
3_多模态对话
定义 ChatController 接口,让它支持文件上传和多模态对话。
@RestController
@RequestMapping("/ai")
@RequiredArgsConstructor
public class ChatController {
private final ChatClient chatClient;
private final ChatHistoryRepository chatHistoryRepository;
@RequestMapping(value = "/chat", produces = "text/html;charset=utf-8")
public Flux<String> chat(String prompt, String chatId, List<MultipartFile> files) {
// 请求聊天前先保存会话id,已经做了重复添加的校验
chatHistoryRepository.save("chat", chatId);
// 请求文本模型
if (files == null || files.isEmpty()) {
return textChat(prompt, chatId);
}
// 多模态模型
return multiModelChat(prompt, chatId, files);
}
private Flux<String> multiModelChat(String prompt, String chatId,
@RequestParam(required = false) List<MultipartFile> files) {
//1.解析多媒体
List<Media> medias = files.stream().map(file ->
new Media(
MimeType.valueOf(Objects.requireNonNull(file.getContentType())),
file.getResource()
)).toList();
return chatClient.prompt()
.user(u -> u.text(prompt).media(medias.toArray(Media[]::new)))
.advisors(a -> a.param(ChatMemory.CONVERSATION_ID, chatId))
.stream().content();
}
private Flux<String> textChat(String prompt, String chatId) {
return chatClient.prompt()
.user(prompt)
.advisors(a -> a.param(ChatMemory.CONVERSATION_ID, chatId))
.stream().content();
}
}
4_测试
进入聊天页面,可以上传图片让 AI 来识别了:
但是存在其他问题,比如对于音频数据格式的解析 qwen 与 OpenAI 并不兼容,所以会报错。
可以使用 spring-alibaba-ai
,或者重写 OpenAiModel 的实现逻辑。