摘要 :本文将通过构建一个简单的
聊天机器人
作为切入点,对AI
技术中大语言模型的基本原理和核心机制进行深入剖析。通过阅读本文,你可以快速了解市面上大部分大模型的接入原理,并具备快速对接
通义
大模型的能力。
前言
人工智能已经成为当今科技领域最受关注的热点话题之一。无论是技术专业人士,还是普通大众,都难以避免的与这一快速发展的技术产生关联。随着AI
技术在各行各业的广泛渗透,各种创新的AI
应用如雨后春笋般涌现,极大地推动了传统开发模式的转型与进步,同时也带来了无数新的机遇。
本文将通过构建一个简单的聊天机器人
作为切入点,逐步探讨AI
技术中大语言模型的基本原理和核心机制。
基础知识
开始之前,我们首先补充一点机器学习的基础知识。总的来说,机器学习主要分为:监督式学习(Supervised Learning)
和非监督式学习(Unsupervised Learning
)两种方式。
具体来看,所谓的监督学习 其实是指在训练过程中,我们需要提供一组带标签的样本数据。这些样本包括了特征数据和对应的标签,机器学习算法通过分析这些数据,从而掌握知识中的规律。然后,便可以基于学到的规律运用于、那些未标注的数据进行分类或预测。
例如,假设我们需要构建一个识别手写数字的应用。我们首先需要尽可能多的收集手写数字图像,并为每张图像手动进行标注,而这些已标注的数据被称为训练数据 ,然后,将相关数据"喂"给机器学习算法去学习,从而让模型能够学习到不同手写数字的特征,提取出其规律和模式,进而最终利用这些规律去识别未标注的手写数字。监督式学习整个过程如下图所示:
无监督学习 与监督式学习 的不同之处在于非监督式学习 所用的数据是没有标签的。因此,无监督机器学习算法的任务是从这些未标注的数据中发现潜在的规律或模式。由于大部分数据未被标注,非监督式学习能够更有效地利用大量未标记的数据,从而挖掘出更多有价值的信息。
例如,假设我们有大量的用户购买数据,但我们很难直接找到用户属性和购买商品之间的关系。非监督式学习算法能够帮助我们发现这些隐藏的关联,比如某个年龄段的女性购买了某种特定品牌的肥皂,这可能意味着她处于怀孕期;或者某人购买儿童用品,可能说明他有孩子。通过这些发现,商家可以进行精准的市场营销,从而提高销售效果。无监督式学习整个过程如下图所示:
了解了机器学习中监督学习和无监督学习后,接下来我们便对大语言模型LLM
的原理进行一个简单介绍。
LLM
背后的原理
大语言模型LLM
其实是用于做自然语言相关任务的深度学习模型,简单来看其原理可以归结为下图所示。即给模型一些文本输入,他可以返回相应的任务。其任务可以是生成、总结、改写等。
进一步来看,大语言模型首先通过大量文本进行大量文本进行无监督学习。以我们熟知的chatGpt
来看其语言数据便来自于多个互联网文本语料库。在如此海量的数据量下,模型能借助算法来更好的理解单词上下的语境关系,从而更好理解文本含义。而为了能更好的实现模型效果,也就需要不断的对模型参数进行调整。
这里的参数其实有点类似我们编程语言中的变量,但在大模型中这里所谈及的变量其实更多的表示训练过程中学到的知识。从一定程度上来说,参数决定了模型如何对输入数据时的反应,也即参数对最终模型的行为有着很强的影响。这也就是为什么算法工程师有时也被称为调参工程师的原因所在。
事实上,在业内通常有这样一种共识即模型参数越多,模型所带来的表现也就更好 。这也就导致如今大语言模型的参数可能达到数百万之多,以我们熟知的GPT3
为例来看,其所用到的参数便高到1700
亿之多。
回顾大模型的发展历史,其最早的开端可追溯于《Attention is All You Need》
论文的问世,著名的Transformer
结构也就是这篇文章中提出的。同时,Transformer
也是无数大模型的基础。换言之,要了解大模型底层原理就无法跳过Transformer
。
正如论文《Attention is All You Need》
标题那样,注意力就是你所需要的一切。简单来说Transformer
在处理文本输入的每个词时不仅会注意到词本身的位置以及其附近的词,其还会注意输入序列里其他的输入内容。然后为为单词赋予不一样的注意力权重。而权重则是在训练过程中通过大量文本逐渐习得的。因此,Transformer
有能力知道当前这个词和其他词之间的关联性,从而更能专注于输入里真正重要的部分。
比如,"The animal didn't cross the street because it was too tired
"这句话其中的it
可以指期最前面的的animal
也可以指靠近it
的street
。但通过自注意机制捕获到了其与animal
之间的根强关系,所以这里的it
更集中在animal
之上!
也正是有了自注意机制,使得Transformer
在捕捉长距离依赖、建模全局信息等方面尽显优势。其与传统RNN
和LSTM
相比,自注意力能够避免顺序计算的局限性,支持全局信息的直接交互,提升了模型的灵活性和表达能力。此外,自注意力的并行化特点和可扩展性使得Transformer
在大规模训练和复杂任务中具有更高的计算效率和适应性,成为现代深度学习中的核心架构。
至此,我们就对大模型中的底层原理进行了简单的介绍。如果对这方面感兴趣的读者,可到The Illustrated Transformer对Transformer
进行深入了解。
介绍完大模型的基础原理后,接下来我们就通过实践的方式来调用大模型的Api
从而构建一个简易的客服
机器人。
十行代码构建简易聊天机器人
注:本文通过调用
阿里
提供的千问大语言模型进行应用构建,当然市面上也有例如百度的千帆大模型,chatGpt等等,这些平台都有提供大模型对应的Api
调用方式,感兴趣的可自行了解~
其实目前国内提供的众多大模型在使用上的方式都大同小异,基本都是通过Http
调用的方式来访问其暴露出的Api
,从而提供相应的AI
功能。在接入阿里
的千问
大模型时,我们首先需要在百炼平台申请相应的密钥信息,以供我们可以顺利调用相关的Api
服务。当申请完毕后,接下来就是应用的构建了。
本次我们用到的核心依赖为alibaba-ai
xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-ai</artifactId>
<version>2023.0.1.3</version>
</dependency>
这里要注意一点,如果要确保spring-cloud-starter-alibaba-ai
成功集成,那么首先要确保系统
的JDK
版本至少是17以上。这主是因为 spring-cloud-starter-alibaba-ai
是基于Spring Boot 3.x
版本开发的,而Spring Boot 3.x
版本要求JDK 17
或更高版本。
除此之外,当项目引入spring-cloud-starter-alibaba-ai
时,如果你使用aliyun
的maven
进行仓库,那么当你在构建maven
依赖时可能还会提示有could not find artifact org.springframework.ai:spring-ai-core:pom:0.8.1
,导致这一问题主要原因在于Spring AI
的0.8.1
版本没有被发布到阿里云的Maven Central
仓库。而为了解决这一问题,我们需要手动在pom
文件中配置如下仓库信息:
xml
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
当解决了上述两个问题后,接下来我们就可以进行对应用的构建了。而我们的应用其实也非常简单,无非就是一个简单的SpringBoot
的Web
应用。相关代码如下:
java
@RestController
@RequestMapping("/chat")
public class ChatController {
@Autowired
private ChatService aiService;
@GetMapping("/msg")
public String sendMessage(String message) {
return aiService.chat(message);
}
}
java
@Service
@Slf4j
public class ChatService {
@Autowired
private final TongYiChatModel tongYiChatModel;
public String chat(String msg) {
Prompt prompt = new Prompt(new UserMessage(msg));
return tongYiChatModel.call(prompt)
.getResult().getOutput().getContent();
}
}
上述代码其实非常简单,首先我们构建一个ChatController
的控制层,以提供可以对外访问的的Api
接口,而ChatController
的sendMessage
方法,则通过调用ChatService
中的chat
方法来实现对通义
大模型Api
接口的调用。
随后,启动我们的应用,然后尝试调用http://localhost:8080/chat/msg
,其结果如下:
至此,我们也就完成了阿里
的通义的集成,并成功构建出一个对应的聊天应用。其实整个过程还是非常简单的,与我们平时构建应用并无太大差异。细心的读者可能会注意到我们在调用通义
的相关Api
时,并没出现相关Http
的调用。这似乎与我们开头所述相悖,接下来我们便对这其中原理进行一定分析。
通义
模型调用分析
可以看到,我们在调用tongYiChatModel.call(prompt)
进而获取到对应的返回结果,从而在提取其后续返回内容。那call
内部又进行了哪些操作呢,我们进入到call
方法内部可以看到其逻辑如下:
java
public ChatResponse call(Prompt prompt) {
<1> 构建大模型请求参数
ConversationParam params = toTongYiChatParams(prompt);
<2> 调用大模型
GenerationResult chatCompletions = this.callWithFunctionSupport(params);
<3> 构建返回响应信息
List<org.springframework.ai.chat.model.Generation> generations =
chatCompletions
.getOutput()
.getChoices()
.stream()
.map(choice ->
new org.springframework.ai.chat.model.Generation(
choice
.getMessage()
.getContent()
).withGenerationMetadata(generateChoiceMetadata(choice)
))
.toList();
return new ChatResponse(generations);
}
不难看出,call
方法内部的逻辑其实无非就是构建参数,然后解析返回响应信息。而对于大模型的调用则在<2>
处进行调用。而对于callWithFunctionSupport
的内部则会调用 OkHttpHttpClient
中的send
方法来发起http
调用。具体调用信息如下:
不难看出,在通义
模型内部,其最终会请求https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation
接口,从而实现对大模型的调用。事实上,这也是ChatGp3
火起来时诸多套壳Gpt
应用背后的原理~
总结
回顾本文,我们首先对机器学习的中的监督学习和无监督学习进行了深入的介绍和分析,在此基础上我们对大语言模型LLM
的原理和机制进行深入的拆解。在了解了LLM
的工作原理后,我们以阿里通义
大模型为技术选型,快速构建出一个可对话的客服机器人,同时对通义
大模型背后调用的原理进行了深入剖析。