【AI大模型】通义千问:开启语言模型新篇章与Function Call技术的应用探索

在这里插入图片描述



前言

    在人工智能的不断演进中,大模型正成为技术革新的先锋。这些模型以其庞大的规模和深刻的理解力,开启了智能应用的新篇章。本文将精炼地探讨大模型的核心概念、发展历程,以及它们在多个场景下的实际应用。
    我们将重点介绍通义千问,这一前沿的语言模型,它在技术突破和实际应用中展现了卓越的灵活性和广泛性。从单轮到多轮对话,从实时交互到异步通信,通义千问的应用场景广泛而深远。
    此外,文章还将讨论大模型面对的挑战,例如实时性问题和特定领域知识的处理,并探索Function call技术如何帮助提升其性能。这不仅是对大模型现有能力的评估,也是对其未来应用潜力的展望。


一、大语言模型

1.大模型介绍

    大语言模型(Large Language Model,缩写LLM),也称大型语言模型,是一种人工智能模型,旨在理解和生成人类语言。

    通常,大语言模型(LLM)指包含数百亿(或更多)参数的语言模型,这些模型在大量的文本数据上进行训练,例如国外的有GPT-3、GPT-4、PaLM、Galactica和LLaMA等,国内的有ChatGLM、文心一言、通义千问、讯飞星火等。

2.大模型的发展历程

在这里插入图片描述

萌芽期(1950-2005):以 CNN 为代表的传统神经网络模型阶段

  • 1956 年,从计算机专家约翰·麦卡锡提出“人工智能”概念开始,AI 发展由最开始基于小规模专家知识逐步发展为基于机器学习。
  • 1980 年,卷积神经网络的雏形 CNN 诞生。
  • 1998 年,现代卷积神经网络的基本结构 LeNet-5 诞生,机器学习方法由早期基于浅层机器学习的模型,变为了基于深度学习的模型,为自然语言生成、计算机视觉等领域的深入研究奠定了基础,对后续深度学习框架的迭代及大模型发展具有开创性的意义。

探索沉淀期(2006-2019):以 Transformer 为代表的全新神经网络模型阶段

  • 2013 年,自然语言处理模型 Word2Vec 诞生,首次提出将单词转换为向量的“词向量模型”,以便计算机更好地理解和处理文本数据。
  • 2014 年,被誉为 21 世纪最强大算法模型之一的 GAN(对抗式生成网络)诞生,标志着深度学习进入了生成模型研究的新阶段。
  • 2017 年,Google 颠覆性地提出了基于自注意力机制的神经网络结构——Transformer 架构,奠定了大模型预训练算法架构的基础。
  • 2018 年,OpenAI 和 Google 分别发布了 GPT-1 与 BERT 大模型,意味着预训练大模型成为自然语言处理领域的主流。在探索期,以 Transformer 为代表的全新神经网络架构,奠定了大模型的算法架构基础,使大模型技术的性能得到了显著提升。

迅猛发展期(2020-至今):以 GPT 为代表的预训练大模型阶段

  • 2020 年,OpenAI 公司推出了GPT-3,模型参数规模达到了 1750 亿,成为当时最大的语言模型,并且在零样本学习任务上实现了巨大性能提升。随后,更多策略如基于人类反馈的强化学习(RHLF)、代码预训练、指令微调等开始出现, 被用于进一步提高推理能力和任务泛化。
  • 2022 年 11 月,搭载了GPT3.5的 ChatGPT横空出世,凭借逼真的自然语言交互与多场景内容生成能力,迅速引爆互联网。
  • 2023 年 3 月,最新发布的超大规模多模态预训练大模型——GPT-4,具备了多模态理解与多类型内容生成能力。在迅猛发展期,大数据、大算力和大算法完美结合,大幅提升了大模型的预训练和生成能力以及多模态多场景应用能力。如 ChatGPT 的巨大成功,就是在微软Azure强大的算力以及 wiki 等海量数据支持下,在 Transformer 架构基础上,坚持 GPT 模型及人类反馈的强化学习(RLHF)进行精调的策略下取得的。

在这里插入图片描述

3.大模型的分类

a.按内容分类

  • 语言大模型(NLP):是指在自然语言处理(Natural Language Processing,NLP)领域中的一类大模型,通常用于处理文本数据和理解自然语言。 这类大模型的主要特点是它们在大规模语料库上进行了训练,以学习自然语言的各种语法、语义和语境规则。例如:GPT 系列(OpenAI)、Bard(Google)、文心一言(百度)。
  • 视觉大模型(CV):是指在计算机视觉(Computer Vision,CV)领域中使用的大模型,通常用于图像处理和分析。 这类模型通过在大规模图像数据上进行训练,可以实现各种视觉任务,如图像分类、目标检测、图像分割、姿态估计、人脸识别等。例如:VIT 系列(Google)、文心UFO、华为盘古 CV、INTERN(商汤)。
  • 多模态大模型:是指能够处理多种不同类型数据的大模型,例如文本、图像、音频等多模态数据。 这类模型结合了 NLP 和 CV 的能力,以实现对多模态信息的综合理解和分析,从而能够更全面地理解和处理复杂的数据。例如:DingoDB 多模向量数据库(九章云极 DataCanvas)、DALL-E(OpenAI)、悟空画画(华为)、midjourney。

b.按应用分类

  • 通用大模型 L0:是指可以在多个领域和任务上通用的大模型。 它们利用大算力、使用海量的开放数据与具有巨量参数的深度学习算法,在大规模无标注数据上进行训练,以寻找特征并发现规律,进而形成可“举一反三”的强大泛化能力,可在不进行微调或少量微调的情况下完成多场景任务,相当于 AI 完成了“通识教育”。
  • 行业大模型 L1:是指那些针对特定行业或领域的大模型。 它们通常使用行业相关的数据进行预训练或微调,以提高在该领域的性能和准确度,相当于 AI 成为“行业专家”。
  • 垂直大模型 L2:是指那些针对特定任务或场景的大模型。 它们通常使用任务相关的数据进行预训练或微调,以提高在该任务上的性能和效果。

二、通义千问

1.通义千问模型介绍

a.通义千问模型介绍

    通义千问是由阿里云自主研发的大语言模型,用于理解和分析用户输入的自然语言,在不同领域和任务为用户提供服务和帮助。您可以通过提供尽可能清晰详细的指令,来获取符合您预期的结果。

b.应用场景

通义千问凭借其强大的语言处理能力,为用户带来高效、智能的语言服务体验,其能力包括但不限于文字创作、翻译服务和对话模拟等,具体应用场景如下:

  • 文字创作:撰写故事、公文、邮件、剧本和诗歌等。
  • 文本处理:润色文本和提取文本摘要等。
  • 编程辅助:编写和优化代码等。
  • 翻译服务:提供各类语言的翻译服务,如英语、日语、法语或西班牙语等。
  • 对话模拟:扮演不同角色进行交互式对话。
  • 数据可视化:图表制作和数据呈现等。

c.模型概览

模型名称模型简介模型输入/输出限制
qwen-turbo通义千问超大规模语言模型,支持中文、英文等不同语言输入。模型支持8k tokens上下文,为了保证正常的使用和输出,API限定用户输入为6k tokens
qwen-plus通义千问超大规模语言模型增强版,支持中文、英文等不同语言输入。模型支持32k tokens上下文,为了保证正常的使用和输出,API限定用户输入为30k tokens
qwen-max通义千问千亿级别超大规模语言模型,支持中文、英文等不同语言输入。随着模型的升级,qwen-max将滚动更新升级。如果希望使用固定版本,请使用历史快照版本。当前qwen-max模型与qwen-max-0428快照版本等价,均为最新版本的qwen-max模型,也是当前通义千问2.5产品版本背后的API模型模型支持8k tokens上下文,为了保证正常的使用和输出,API限定用户输入为6k tokens
qwen-max-0428通义千问千亿级别超大规模语言模型,支持中文、英文等不同语言输入。该模型与当前的qwen-max版本对齐,为qwen-max的2024年4月28号的历史快照,预期维护到下个快照版本发布时间(待定)后一个月。
qwen-max-0403通义千问千亿级别超大规模语言模型,支持中文、英文等不同语言输入。该模型为qwen-max的2024年4月3号的历史快照稳定版本,预期维护到下个快照版本发布时间(待定)后一个月。
qwen-max-0107通义千问千亿级别超大规模语言模型,支持中文、英文等不同语言输入。该模型为qwen-max的2024年1月7号的历史快照稳定版本,仅推荐特定需求客户访问。
qwen-max-longcontext通义千问千亿级别超大规模语言模型,支持中文、英文等不同语言输入。模型支持30k tokens上下文,为了保证正常的使用和输出,API限定用户输入为28k tokens

2.对话

a.对话的两种方式

可以通过两种方式来调用模型:通过messages调用或通过prompt调用。如果有多轮对话的需求,更推荐通过messages调用

通义千问API的使用

步骤流程:

1.去阿里云 DashScope 模型服务灵积 创建API-KEY
https://dashscope.console.aliyun.com/apiKey

在这里插入图片描述
2.在 DashScope 模型服务灵积/模型广场 选择通义千问模型 - 快速开始
https://dashscope.console.aliyun.com/model

在这里插入图片描述
3.进入后,有通义千问API详细且完整的使用文档
PS:测试API前记得安装DashScope SDK,通过环境变量配置API-KEY
在这里插入图片描述

b.单轮对话

    单轮对话是指用户提出一个问题或请求,系统立即给出回答或响应,不涉及后续的多轮追问或讨论。 这种形式常见于搜索引擎查询、聊天机器人等场景。它的优势在于高效和便捷,能够快速提供信息或答案。然而,单轮对话可能无法完全理解复杂的用户需求或提供深入的解答。因此,在实际应用中,单轮对话常与其他交互方式结合使用,以提高服务的全面性和准确性。

Vue页面代码:
<template>
  <div>
  
  <el-form :inline="true" :model="formInline" class="demo-form-inline">
  <el-form-item label="问题">
    <el-input v-model="formInline.askmes" placeholder="请输入问题"></el-input>
  </el-form-item>
  
  <el-form-item>
    <el-button type="primary" @click="onSubmit">查询</el-button>
  </el-form-item>
</el-form>

<div>
  {{mes}}
  </div>

  </div>
</template>

<script>
export default {
  data() {
      return {
        formInline: {
          askmes:'',
        },
         mes:''
      }
    },
    methods: {
      onSubmit() {
        console.log('submit!');
        this.$axios.post('tongyi/',{"question":this.formInline.askmes}).then(res=>{
          
            this.mes = res.data.mes
        })
      }
    }

}
</script>

<style>

</style>
Django接口代码
import random
from http import HTTPStatus
from dashscope import Generation  # 建议dashscope SDK 的版本 >= 1.14.0
           
class TongyiView(APIView):
    def post(self,request):
        question = request.data.get('question')
        
        messages = [{'role': 'system', 'content': 'You are a helpful assistant.'},
                {'role': 'user', 'content': question}]
        response = Generation.call(model="qwen-turbo",
                                messages=messages,
                                # 设置随机数种子seed,如果没有设置,则随机数种子默认为1234
                                seed=random.randint(1, 10000),
                                # 将输出设置为"message"格式
                                result_format='message')
        if response.status_code == HTTPStatus.OK:
            print(response)
            print(response['output']['choices'][0]['message']['content'])
            resmes= response['output']['choices'][0]['message']['content']
            # response = json.loads(response.message)
            # resmes = response['output']['choices']['message']['content']
        else:
            print('Request id: %s, Status code: %s, error code: %s, error message: %s' % (
                response.request_id, response.status_code,
                response.code, response.message
            ))
            resmes = response.message


        return Response({"code":200,'mes':resmes})

c.多轮对话

比于单轮对话,多轮对话可以参考历史聊天信息,更符合日常交流的场景。但由于调用时会引入历史聊天信息,使用的token量会增多。

实现流程分析:

  • 1.设计问题,定义角色role为user
  • 2.获取响应解析,判断
  • 3.如果成功将assistant的回复添加到messages列表中
  • 4.如果响应失败,将最后一条user message从messages列表里删除,确保user/assistant消息交替出现
  • 5.将新一轮的user问题添加到messages列表中
  • 6.进行第二轮模型的响应
from http import HTTPStatus
from dashscope import Generation


def multi_round():
    messages = [{'role': 'system', 'content': 'You are a helpful assistant.'},
                {'role': 'user', 'content': '如何做西红柿炖牛腩?'}]
    response = Generation.call(model="qwen-turbo",
                               messages=messages,
                               # 将输出设置为"message"格式
                               result_format='message')
    if response.status_code == HTTPStatus.OK:
        print(response)
        # 将assistant的回复添加到messages列表中
        messages.append({'role': response.output.choices[0]['message']['role'],
                         'content': response.output.choices[0]['message']['content']})
    else:
        print('Request id: %s, Status code: %s, error code: %s, error message: %s' % (
            response.request_id, response.status_code,
            response.code, response.message
        ))
        # 如果响应失败,将最后一条user message从messages列表里删除,确保user/assistant消息交替出现
        messages = messages[:-1]
    # 将新一轮的user问题添加到messages列表中
    messages.append({'role': 'user', 'content': '不放糖可以吗?'})
    # 进行第二轮模型的响应
    response = Generation.call(model="qwen-turbo",
                               messages=messages,
                               result_format='message',  # 将输出设置为"message"格式
                               )
    if response.status_code == HTTPStatus.OK:
        print(response)
    else:
        print('Request id: %s, Status code: %s, error code: %s, error message: %s' % (
            response.request_id, response.status_code,
            response.code, response.message
        ))


if __name__ == '__main__':
    multi_round()

3.实时交互功能

实现流程分析

  • 1.导入 Generation类
  • 2.封装对话应用的模型和消息
  • 3.定义消息messages
  • 4.定义对话的轮数
  • 5.输入问题,创建角色为role
  • 6.获取结果响应,把结果添加到messages中
from dashscope import Generation

def get_response(messages):
    response = Generation.call(model="qwen-turbo",
                               messages=messages,
                               # 将输出设置为"message"格式
                               result_format='message')
    return response


messages = [{'role': 'system', 'content': 'You are a helpful assistant.'}]

# 您可以自定义设置对话轮数,当前为3
for i in range(3):
    user_input = input("请输入:")
    messages.append({'role': 'user', 'content': user_input})
    assistant_output = get_response(messages).output.choices[0]['message']['content']
    messages.append({'role': 'assistant', 'content': assistant_output})
    print(f'用户输入:{user_input}')
    print(f'模型输出:{assistant_output}')
    print('\n')

4.流式响应

    大模型并不是一次性生成最终结果,而是逐步地生成中间结果,最终结果由中间结果拼接而成。非流式输出方式等待模型生成结束后再将生成的中间结果拼接后返回,而流式输出可以实时地将中间结果返回,您可以在模型进行输出的同时进行阅读,减少等待模型回复的时间。使用流式输出需要您进行一些配置,DashScope Python SDK中需要设置stream为True,DashScope Java SDK中需要使用streamCall接口调用。

流式输出的流程和正常的一样,在响应中指定 stream=True, # 设置输出方式为流式输出

from http import HTTPStatus
from dashscope import Generation


def call_with_stream():
    messages = [
        {'role': 'user', 'content': '如何做西红柿炖牛腩?'}]
    responses = Generation.call(model="qwen-turbo",
                                messages=messages,
                                result_format='message',  # 设置输出为'message'格式
                                stream=True,  # 设置输出方式为流式输出
                                incremental_output=True  # 增量式流式输出
                                )
    for response in responses:
        if response.status_code == HTTPStatus.OK:
            print(response.output.choices[0]['message']['content'], end='')
        else:
            print('Request id: %s, Status code: %s, error code: %s, error message: %s' % (
                response.request_id, response.status_code,
                response.code, response.message
            ))


if __name__ == '__main__':
    call_with_stream()

5.异步Asyncio接口

如果使用Dashscope Python SDK,可以使用asyncio调用实现并发,提高程序的效率。(Dashscope Python SDK版本需要不低于 1.19.0)

import asyncio
from http import HTTPStatus
import platform

from dashscope import Generation
from dashscope.aigc.generation import AioGeneration


async def async_dashscope_sample():
    response = await AioGeneration.call("qwen-turbo",
                                        prompt='今天天气好吗?')

    if response.status_code == HTTPStatus.OK:
        print('Result is: %s' % response.output)
    else:
        print('Failed request_id: %s, status_code: %s, code: %s, message:%s' %
              (response.request_id, response.status_code, response.code,
               response.message))


async def async_dashscope_stream_sample():
    responses = await AioGeneration.call(model="qwen-turbo",
                                         prompt='今天天气好吗?',
                                         stream=True)
    # responses是async迭代器,需要用async for循环来遍历
    async for response in responses:
        print(response)


async def main():
    response = await async_dashscope_sample()
    print(response)
    await async_dashscope_stream_sample()
if __name__ == '__main__':
    # 如果当前操作系统为Windows,则使用WindowsSelectorEventLoopPolicy作为事件循环策略
    if platform.system() == 'Windows':
        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    asyncio.run(main(), debug=False)

6.Function call

    大模型在面对实时性问题、私域知识型问题或数学计算等问题时可能效果不佳。您可以使用function call功能,通过调用外部工具来提升模型的输出效果。您可以在调用大模型时,通过tools参数传入工具的名称、描述、入参等信息。大模型在收到提示词以及工具信息后,会判断是否需要使用工具:

  • 如果不需要使用工具,大模型不会返回tool_calls参数,您的程序可以直接返回大模型的回答。
  • 如果需要使用工具,大模型会返回一个包含tool_calls字段的信息,您的程序可以根据此信息判断需要调用工具。您的程序需要解析tool_calls信息中包含的工具函数名和入参,并将入参输入到工具函数来得到工具调用的结果。

格式配置

{
    "name": "$工具名",
    "role": "tool",
    "content": "$工具输出"
}

流程分析:

  • 1.定义工具列表,模型在选择使用哪个工具时会参考工具的name和description
  • 2.工具1 获取当前时刻的时间
  • 3.工具2 获取指定城市的天气
  • 4.查询天气时需要提供位置,因此参数设置为location
  • 5.模拟天气查询工具。返回结果示例:“北京今天是晴天。”
  • 6.查询当前时间的工具。返回结果示例:“当前时间:2024-04-15 17:15:18。“
  • 7.封装模型响应函数
from dashscope import Generation
from datetime import datetime
import random
import json


# 定义工具列表,模型在选择使用哪个工具时会参考工具的name和description
tools = [
    # 工具1 获取当前时刻的时间
    {
        "type": "function",
        "function": {
            "name": "get_current_time",
            "description": "当你想知道现在的时间时非常有用。",
            "parameters": {}  # 因为获取当前时间无需输入参数,因此parameters为空字典
        }
    },  
    # 工具2 获取指定城市的天气
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "当你想查询指定城市的天气时非常有用。",
            "parameters": {  # 查询天气时需要提供位置,因此参数设置为location
                        "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市或县区,比如北京市、杭州市、余杭区等。"
                    }
                }
            },
            "required": [
                "location"
            ]
        }
    }
]

# 模拟天气查询工具。返回结果示例:“北京今天是晴天。”
def get_current_weather(location):
    return f"{location}今天是晴天。 "

# 查询当前时间的工具。返回结果示例:“当前时间:2024-04-15 17:15:18。“
def get_current_time():
    # 获取当前日期和时间
    current_datetime = datetime.now()
    # 格式化当前日期和时间
    formatted_time = current_datetime.strftime('%Y-%m-%d %H:%M:%S')
    # 返回格式化后的当前时间
    return f"当前时间:{formatted_time}。"

# 封装模型响应函数
def get_response(messages):
    response = Generation.call(
        model='qwen-max',
        messages=messages,
        tools=tools,
        seed=random.randint(1, 10000),  # 设置随机数种子seed,如果没有设置,则随机数种子默认为1234
        result_format='message'  # 将输出设置为message形式
    )
    return response

def call_with_messages():
    print('\n')
    messages = [
            {
                "content": input('请输入:'),  # 提问示例:"现在几点了?" "一个小时后几点" "北京天气如何?"
                "role": "user"
            }
    ]
    
    # 模型的第一轮调用
    first_response = get_response(messages)
    assistant_output = first_response.output.choices[0].message
    print(f"\n大模型第一轮输出信息:{first_response}\n")
    messages.append(assistant_output)
    if 'tool_calls' not in assistant_output:  # 如果模型判断无需调用工具,则将assistant的回复直接打印出来,无需进行模型的第二轮调用
        print(f"最终答案:{assistant_output.content}")
        return
    # 如果模型选择的工具是get_current_weather
    elif assistant_output.tool_calls[0]['function']['name'] == 'get_current_weather':
        tool_info = {"name": "get_current_weather", "role":"tool"}
        location = json.loads(assistant_output.tool_calls[0]['function']['arguments'])['properties']['location']
        tool_info['content'] = get_current_weather(location)
    # 如果模型选择的工具是get_current_time
    elif assistant_output.tool_calls[0]['function']['name'] == 'get_current_time':
        tool_info = {"name": "get_current_time", "role":"tool"}
        tool_info['content'] = get_current_time()
    print(f"工具输出信息:{tool_info['content']}\n")
    messages.append(tool_info)

    # 模型的第二轮调用,对工具的输出进行总结
    second_response = get_response(messages)
    print(f"大模型第二轮输出信息:{second_response}\n")
    print(f"最终答案:{second_response.output.choices[0].message['content']}")

if __name__ == '__main__':
    call_with_messages()
    

上面示例代码中天气工具返回结果是固定的,可以使用高德地图提供的接口进行完善天气工具的代码完善。很简单~ 感兴趣的友友们可以自己完善一下~


在这里插入图片描述

  • 134
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 130
    评论
评论 130
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

么凹猫'

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值