【Java-LangChain:使用 ChatGPT API 搭建系统-2】语言模型,提问范式与 Token

news2025/1/15 12:46:58

第二章 语言模型,提问范式与 Token

在本章中,我们将和您分享大型语言模型(LLM)的工作原理、训练方式以及分词器(tokenizer)等细节对 LLM 输出的影响。我们还将介绍 LLM 的提问范式(chat format),这是一种指定系统消息(system message)和用户消息(user message)的方式,让您了解如何利用这种能力。

一,环境配置

Helper function 辅助函数。
如果之前曾参加过《ChatGPT Prompt Engineering for Developers》课程,那么对此就相对较为熟悉。 调用该函数输入 Prompt 其将会给出对应的 Completion 。


    public String getCompletion(String prompt) {
    
        ChatCompletionRequest chatCompletionRequest = new ChatCompletionRequest();

        chatCompletionRequest.setModel("gpt-3.5-turbo");
        chatCompletionRequest.setTemperature(0d);

        ChatMessage chatMessage = new ChatMessage();
        chatMessage.setRole("user");
        chatMessage.setContent(prompt);

        chatCompletionRequest.setMessages(Arrays.asList(chatMessage));

        ChatCompletionResult result = openAiService.createChatCompletion(chatCompletionRequest);

        ChatMessage chatMessage1 = result.getChoices().get(0).getMessage();

        return chatMessage1.getContent();
    }

二,尝试向模型提问并得到结果

LLM 可以通过使用监督学习来构建,通过不断预测下一个词来学习。 并且,给定一个大的训练集,有数百亿甚至更多的词,你可以创建一个大规模的训练集,你可以从一 句话或一段文本的一部分开始,反复要求语言模型学习预测下一个词是什么

LLM 主要分为两种类型:基础语言模型(Base LLM)和越来越受欢迎的指令微调语言模型(Instruction Tuned LLM)。基础语言模型通过反复预测下一个词来训练,因此如果我们给它一个 Prompt,比如“从前有一只独角兽”,它可能通过逐词预测来完成一个关于独角兽在魔法森林中与其他独角兽朋友们生活的故事。

然而,这种方法的缺点是,如果您给它一个 Prompt,比如“中国的首都是哪里?”,很可能它数据中有一段互联网上关于中国的测验问题列表。这时,它可能会用“中国最大的城市是什么?中国的人口是多少?”等等来回答这个问题。但实际上,您只是想知道中国的首都是什么,而不是列举所有这些问题。然而,指令微调语言模型会尝试遵循 Prompt,并给出“中国的首都是北京”的回答。

那么,如何将基础语言模型转变为指令微调语言模型呢?这就是训练一个指令微调语言模型(例如ChatGPT)的过程。首先,您需要在大量数据上训练基础语言模型,因此需要数千亿个单词,甚至更多。这个过程在大型超级计算系统上可能需要数月时间。训练完基础语言模型后,您会通过在一小部分示例上进行进一步的训练,使模型的输出符合输入的指令。例如,您可以请承包商帮助您编写许多指令示例,并对这些指令的正确回答进行训练。这样就创建了一个用于微调的训练集,让模型学会在遵循指令的情况下预测下一个词是什么。

之后,为了提高语言模型输出的质量,常见的方法是让人类对许多不同输出进行评级,例如是否有用、是否真实、是否无害等。然后,您可以进一步调整语言模型,增加生成高评级输出的概率。这通常使用强化学习中的人类反馈(RLHF)技术来实现。相较于训练基础语言模型可能需要数月的时间,从基础语言模型到指令微调语言模型的转变过程可能只需要数天时间,使用较小规模的数据集和计算资源。


        String prompt = "中国的首都是哪里?";

        String message = this.getCompletion(prompt);

        log.info("iterative1:\n{}", message);

中国的首都是北京。

三,Tokens

到目前为止对 LLM 的描述中,我们将其描述为一次预测一个单词,但实际上还有一个更重要的技术细节。即 LLM 实际上并不是重复预测下一个单词,而是重复预测下一个 token 。当 LLM 接收到输入时,它将将其转换为一系列 token,其中每个 token 都代表常见的字符序列。
例如,对于 “Learning new things is fun!” 这句话,每个单词都被转换为一个 token ,而对于较少使用的单词,如 “Prompting as powerful developer tool”,单词 “prompting” 会被拆分为三个 token,即"prom"、“pt"和"ing”。
当您要求 ChatGPT 颠倒 “lollipop” 的字母时,由于分词器(tokenizer) 将 “lollipop” 分解为三个 token,即 “l”、“oll”、“ipop”,因此 ChatGPT 难以正确输出字母的顺序。您可以通过在字母之间添加连字符或空格的方式,使分词器将每个字母分解为单独的 token,从而帮助 ChatGPT 更好地认识单词中的每个字母并正确输出它们。

        String prompt = "Take the letters in lollipop \n" +
                "and reverse them";

        String message = this.getCompletion(prompt);

        //The reversed letters of "lollipop" are "pillipol".
        //实际上 lollipop 的 翻转是 popillol
        log.info("test2:\n{}", message);


        String prompt1 = "Take the letters in\n" +
                "l-o-l-l-i-p-o-p and reverse them";

        String message1 = this.getCompletion(prompt1);

        //p-o-p-i-l-l-o-l
        //这次正确了
        log.info("test2:\n{}", message1);
        

对于英文输入,一个 token 一般对应 4 个字符或者四分之三个单词;对于中文输入,一个 token 一般对应一个或半个词。
不同模型有不同的 token 限制,需要注意的是,这里的 token 限制是输入的 Prompt 和输出的 completion 的 token 数之和,因此输入的 Prompt 越长,能输出的 completion 的上限就越低。
ChatGPT3.5-turbo 的 token 上限是 4096。

四,Helper function 辅助函数 (提问范式)

下图是 OpenAI 提供的一种提问范式,接下来吴恩达老师就是在演示如何利用这种范式进行更好的提问

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

System 信息用于指定模型的规则,例如设定、回答准则等,而 assistant 信息就是让模型完成的具体指令


        ChatCompletionRequest chatCompletionRequest = new ChatCompletionRequest();

        //调用的模型,默认为 gpt-3.5-turbo(ChatGPT),有内测资格的用户可以选择 gpt-4\
        chatCompletionRequest.setModel("gpt-3.5-turbo");
        
        //决定模型输出的随机程度,默认为0,表示输出将非常确定。增加温度会使输出更随机。
        chatCompletionRequest.setTemperature(temperature);
        
        //这决定模型输出的最大的 token 数。
        chatCompletionRequest.setMaxTokens(500);
        
        //是一个消息列表,每个消息都是一个字典,包含 role(角色)和 content(内容)。角色可以是'system'、'user' 或 'assistant’,内容是角色的消息。
        chatCompletionRequest.setMessages(chatMessages);

        ChatCompletionResult result = openAiService.createChatCompletion(chatCompletionRequest);

        ChatMessage chatMessage1 = result.getChoices().get(0).getMessage();

        return chatMessage1.getContent();


        List<ChatMessage> chatMessages = new ArrayList<>();

        ChatMessage chatMessage = new ChatMessage();
        chatMessage.setRole("system");
        chatMessage.setContent("你是一个助理, 并以 Seuss 苏斯博士的风格作出回答。");
        chatMessages.add(chatMessage);

        ChatMessage chatMessage2 = new ChatMessage();
        chatMessage2.setRole("user");
        chatMessage2.setContent("就快乐的小鲸鱼为主题给我写一首短诗");
        chatMessages.add(chatMessage2);

        String message1 = this.getCompletionFromMessage(chatMessages, 1);
       
        log.info("test3:\n{}", message1);

test3:
在大海深处有一只小鲸鱼,
游来游去像个顽皮的小露珠。
它喜欢跳跃在波浪中,
展现出它的自由和活力。

它的背上有绚丽的颜色,
像艳阳般明亮,充满温暖的力量。
在阳光下闪烁的小鱼鳍,
给人们带来无尽的欢乐和惊喜。

它和鱼群一起游弋在大海里,
快乐洋溢在每一刻,
它们跳跃、转圈、翻滚,
把欢乐传递给每个人。

小鲸鱼是快乐的使者,
散发着温暖和爱的气息。
让我们跟随它的脚步,
一起享受快乐的时光的魔力。

快乐的小鲸鱼如此独特,
带给我们世界的色彩和美丽。
让我们永远怀抱快乐和希望,
像小鲸鱼一样,自由地飞扬起舞。

        List<ChatMessage> chatMessages = new ArrayList<>();

        ChatMessage chatMessage = new ChatMessage();
        chatMessage.setRole("system");
        
        //长度控制
        chatMessage.setContent("你的所有答复只能是一句话");
        chatMessages.add(chatMessage);

        ChatMessage chatMessage2 = new ChatMessage();
        chatMessage2.setRole("user");
        chatMessage2.setContent("写一个关于快乐的小鲸鱼的故事");
        chatMessages.add(chatMessage2);

        String message1 = this.getCompletionFromMessage(chatMessages, 1);

        log.info("test4:\n{}", message1);
小鲸鱼在海洋里游来游去,快乐地和海洋里的朋友们玩耍,感受着无尽的快乐和自由。

把以上的要求用一句话结合起来

        List<ChatMessage> chatMessages = new ArrayList<>();

        ChatMessage chatMessage = new ChatMessage();
        chatMessage.setRole("system");

        //结合
        chatMessage.setContent("你是一个助理, 并以 Seuss 苏斯博士的风格作出回答,只回答一句话");
        chatMessages.add(chatMessage);

        ChatMessage chatMessage2 = new ChatMessage();
        chatMessage2.setRole("user");
        chatMessage2.setContent("写一个关于快乐的小鲸鱼的故事");
        chatMessages.add(chatMessage2);

        String message1 = this.getCompletionFromMessage(chatMessages, 1);

        log.info("test5:\n{}", message1);
在蓝色的海洋里,快乐的小鲸鱼欢快地跳跃,它的笑声如波浪般荡漾,带来了幸福的感觉。

最后,我们认为 Prompt 对 AI 应用开发的革命性影响仍未得到充分重视低。在传统的监督机器学习工作流中,如果想要构建一个可以将餐厅评论分类为正面或负面的分类器,首先需要获取一大批带有标签的数据,可能需要几百个,这个过程可能需要几周,甚至一个月的时间。接着,您需要在这些数据上训练一个模型,找到一个合适的开源模型,并进行模型的调整和评估,这个阶段可能需要几天、几周,甚至几个月的时间。最后,您可能需要使用云服务来部署模型,将模型上传到云端,并让它运行起来,才能最终调用您的模型。整个过程通常需要一个团队数月时间才能完成。
相比之下,使用基于 Prompt 的机器学习方法,当您有一个文本应用时,只需提供一个简单的 Prompt 就可以了。这个过程可能只需要几分钟,如果需要多次迭代来得到有效的 Prompt 的话,最多几个小时即可完成。在几天内(尽管实际情况通常是几个小时),您就可以通过 API 调用来运行模型,并开始使用。一旦您达到了这个步骤,只需几分钟或几个小时,就可以开始调用模型进行推理。
因此,以前可能需要花费六个月甚至一年时间才能构建的应用,现在只需要几分钟或几个小时,最多是几天的时间,就可以使用 Prompt 构建起来。这种方法正在极大地改变 AI 应用的快速构建方式。

需要注意的是,这种方法适用于许多非结构化数据应用,特别是文本应用,以及越来越多的视觉应用,尽管目前的视觉技术仍在发展中。但它并不适用于结构化数据应用,也就是那些处理 Excel 电子表格中大量数值的机器学习应用。然而,对于适用于这种方法的应用,AI 组件可以被快速构建,并且正在改变整个系统的构建工作流。构建整个系统可能仍然需要几天、几周或更长时间,但至少这部分可以更快地完成。

Java快速转换到大模型开发:
配套课程的所有代码已经发布在:https://github.com/Starcloud-Cloud/java-langchain
课程合作请留言

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1057874.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python开源项目月排行 2023年9月

#2023年9月2023年9月9日1fishdraw这个项目是用来随机生成一条鱼的&#xff0c;这条鱼特别的稀奇古怪&#xff0c;这个项目不依赖任何库&#xff0c;支持 svg, json, csv 等格式。2vizro一个用于创建模块化数据可视化应用程序的工具包。在几分钟内快速自助组装定制仪表板 - 无需…

谈谈Redis分布式锁

目录 一、回顾分布式锁 &#xff08;一&#xff09;理解分布式锁的定义 &#xff08;二&#xff09;分布式锁的约束条件 &#xff08;三&#xff09;分布式锁常见实现方式 基于数据库的分布式锁 基于缓存的分布式锁 基于分布式一致性算法的分布式锁 基于文件系统的分布…

JavaSE | 初始Java(十) | 继承和多态

继承 (inheritance) 机制 &#xff1a;是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保持原有类特性的基础上进行扩展&#xff0c;增加新功能 &#xff0c;这样产生新的类&#xff0c;称 派生类 。继承呈现了面向对象程序设计的层次结构&#xff…

在线教育平台开发:数字化教育的奇妙时代

在今天的数字化时代&#xff0c;教育正在经历着前所未有的变革。在线教育平台的兴起已经改变了传统教育的局面&#xff0c;为学习者和教育者提供了无限的机会。本文将深入探讨在线教育平台开发的关键方面&#xff0c;并穿插一些实际代码示例&#xff0c;以帮助您了解如何创建一…

层次架构、面向服务架构(四十四)

层次架构设计 表现层、中间层、数据访问层、数据架构规划、物联网层次架构、层次式架构案例分析。 层次结构缺点就是效率问题&#xff0c;上一层调用下一层。 1、着重写中间层 组件设计&#xff1a;面向接口编程&#xff0c;分为接口和实现类。 实体设计&#xff1a;实体表…

监狱工具管理系统-监狱劳动工具管理系统

监狱劳动工具管理系统(智工具DW-S308)是依托互3D技术、云计算、大数据、RFID技术、数据库技术、AI、视频分析技术对工具进行统一管理、分析的信息化、智能化、规范化的系统。 当前各级监狱工器具管理更多的是借助于传统的人工管理方法和手段&#xff0c;数据的采集和录入一直以…

作业 day4

完成父子进程通信

Redis的java客户端-RedisTemplate光速入门

一.创建springboot项目 二.引入2个依赖 <!-- redis依赖-->这个已经引入了&#xff0c;因为创建的时候勾选了<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><…

【unity实战】手戳一个库存系统,非常适合RPG、Roguelike和星露谷物语之类的游戏

文章目录 前言素材开始配置不同物品信息实例化物品拾取物品物品栏、库存大小寻找物品栏并可以添加物品库存已满问题解决库存UI脚本显示物品信息切换指示器丢弃物品添加丢弃弹出效果 最终效果源码完结 前言 其实前面我已经做过了很多次背包库存系统了&#xff0c;背包系统实现方…

【计算机网络】数据链路层(学习笔记)

一、数据链路层概述 1、基本概念 1&#xff09;数据链路层模型 2&#xff09;数字管道 常常在两个对等的数据链路层之间画出一个数字管道&#xff0c;而在这条数字管道上传输的数据单位是帧。 3&#xff09;链路与数据链路 链路是一条点到点的物理线路段&#xff0c;中间没…

Vue中如何进行滚动加载与无限滚动

Vue中的滚动加载与无限滚动 滚动加载&#xff08;Infinite Scroll&#xff09;是现代Web应用程序中常见的用户体验功能之一。它允许在用户滚动到页面底部时自动加载更多内容&#xff0c;通常用于分页显示大量数据。Vue.js作为一种流行的前端框架&#xff0c;提供了实现滚动加载…

备忘录:Docker基础操作与常用命令

文章目录 Docker基础操作1.1 Docker在线安装1.1.1 安装基础软件包1.1.2 安装docker主程序1.1.2.1 设置国内源1.1.2.2 安装docker 1.2 Docker离线安装1.2.1 下载离线安装包1.2.2 安装docker依赖包以及docker 1.3 设置自启动并启动dokcer1.4 安装docker-compose1.4.1 命令行下载文…

ADB的概念、使用场景、工作原理

文章目录 一、adb概念&#xff1a;Android Debug Bridge&#xff0c;一个可以控制安卓设备的通用命令行工具二、adb的使用场景&#xff1a;操作手机设备、app 自动化测试1.传输文件2.兼容性测试&#xff08;手机墙&#xff09;3.云测平台4.测试框架底层封装&#xff1a;APP自动…

柠檬水找零【贪心1】

由于是贪心算法的第一道题&#xff0c;所以先介绍一下贪心算法。 贪心策略&#xff1a;一种解决问题的策略&#xff0c;局部最优->全局最优。&#xff08;贪婪鼠目寸光&#xff09; 1、把解决问题的过程分为若干步 2、解决每一步时&#xff0c;都选择当前看起来最优的解法。…

tcp滑动窗口原理

18.1 滑动窗口 我们再来看这个比喻&#xff1a; 网络仅仅是保证了整个网络的连通性&#xff0c;我们我们基于整个网络去传输&#xff0c;那么是不是我想发送多少数据就发送多少数据呢&#xff1f;如果是这样的话&#xff0c;是不是就会像我们的从一个池塘抽水去灌到另外一个…

【Java】微服务——微服务介绍和Eureka注册中心

目录 1.微服务介绍2.服务拆分和远程调用2.1.提供者与消费者 3.Eureka注册中心3.1.Eureka的结构和作用3.2.Eureka的结构3.3.搭建Eureka服务3.3.1.引入eureka依赖3.3.2.编写配置文件 3.4.服务注册及拉1&#xff09;引入依赖2&#xff09;配置文件3&#xff09;启动多个user-servi…

剑指offer——JZ24 反转链表 解题思路与具体代码

一、题目描述与要求 反转链表_牛客题霸_牛客网 (nowcoder.com) 题目描述 给定一个单链表的头结点pHead(该头节点是有值的&#xff0c;比如在下图&#xff0c;它的val是1)&#xff0c;长度为n&#xff0c;反转该链表后&#xff0c;返回新链表的表头。 数据范围&#xff1a; …

Mongodb7启动报错排除解决方案

一&#xff1a; 报错信息: [rootwww log]# journalctl -xe -- Unit mongodb.service has begun starting up. /usr/local/mongodb/mongdb7/bin/mongod --help for more information 10月 03 13:47:39 www.yhchange.com systemd[1]: mongodb.service: control process exited, …

10.03

代码 #include <iostream>using namespace std; class cz { private:int num1; //实部int num2; //虚部 public:cz(){}cz(int a,int b):num1(a),num2(b){}cz(const cz &other):num1(other.num1),num2(other.num2){}~cz(){}const cz operator(const cz &othe…

2023年中国BaaS行业发展概况及未来发展趋势分析:未来多链支持和发展将是BaaS平台发展重点方向[图]

BaaS是指将区块链框架嵌入云计算平台&#xff0c;利用云服务基础设施的部署和管理优势&#xff0c;为开发者提供便捷、高性能的区块链生态环境和生态配套服务&#xff0c;支持开发者的业务拓展及运营支持的区块链开放平台。通常情况下&#xff0c;一套完整的 BaaS 解决方案包括…