Python Docker FastAPI快速开发部署RESTful API

本文介绍如何快速使用Python, Docker, FastAPI快速开发RESTful API,以及如何编译为Docker镜像,使用Docker容器运行程序。 预备知识 在开始开发之前,需要先安装Python和Docker。 Python是一种流行的编程语言,因此在许多操作系统上都可以很容易地安装。可以使用Miniconda,也可以使用官方提供的标准安装包进行安装,个人喜欢Miniconda,不会像Anaconda那么大,同时又提供了非常多必要的依赖模块。 而Docker则是一种容器化平台,可帮助我们轻松地将应用程序封装在容器中,便于部署和管理。目前Windows、Linx、macOS对Docker的支持也非常的完善了。 FastAPI 是一个用于构建 API 的现代、快速(高性能)的 web 框架,使用 Python 3.6+ 并基于标准的 Python 类型提示。 初始化项目及运行环境 Python没有像Java那样极其成熟的一站式的Maven项目管理工具,但是Python有其自身的简洁与规范。像pyproject.toml,以及最近用Rust写的rye,都是很出色的工具。本文使用的例子,完全使用手动管理即可😄 创建一个项目目录my-project,创建文件requirements.txt,main.py,Dockerfile,后面逐一填写里面的内容。 上面我们安装了Miniconda,建议使用conda来创建一个独立的运行环境,这样即不会影响其他项目的运行环境,还可以保持本项目运行环境的整洁。 conda create -n my-project python=3.9 pip 这个命令创建一个名为my-project的运行环境,同时安装3.9版本的Python,和最新的pip工具。 然后激活这个运行环境 conda activate my-project 添加依赖模块 我们使用requirements.txt来管理程序依赖的模块,requirements.txt文件内容如下 -i https://mirrors.aliyun.com/pypi/simple/ fastapi uvicorn[standard] 本文只需要用到这两个模块。第一行的-i指定pip使用阿里pypi镜像地址,如果在国内这会大大加快依赖安装的速度,可以换成阿里或者其他的镜像源。 在本地开发电脑上可以使用下面的命令安装依赖 pip install -r requirements.txt 编写代码 Python代码 FastAPI非常容易使用,也非常适合快速开发RESTful API。以下是我们快速入门的示例代码: from fastapi import FastAPI app = FastAPI() @app.get("/") def read_root(): return "Hello World" @app.get("/items/{item_id}") def read_item(item_id: int, q: str = None): return {"item_id": item_id, "q": q} 在这个简单的示例中,我们创建了一个FastAPI应用程序,它包括两个路由。第一个路由处理根路径并返回一个简单的“Hello World”字符串。第二个路由处理传递给它的路径参数,并返回这些参数的值。第二个路由会以json格式响应内容给调用者(FastAPI框架会自动帮我们字典转换为json数据)。 ...

June 6, 2023

Python函数式编程之 update_in_fn

接上一篇内容 Python函数式编程之自定义函数get_in 。这次我们来编写函数式风格的修改字典/列表值的通用函数。 我们先来假设一种情况,你有一个嵌套的动态字典,想要更新里面某个键对应的值,我们用代码来说明 data = {'a': {'b': 1}} 现在有一个变量data 他的值是一个两层的字典,如果我要更新 b 的值到 2 常规的做法是这样的 data['a]['b'] = 2 如果我有一个更加深的字典 data = {'a': {'b': {'c': {'d': 1}}}} 更新值的写法 data['a']['b']['c']['d''] = 2 这里有一个情况发生了,当 data 是一个动态数组,你不确定中间的某个键是否存在的时候就会有报错 假如这个数据是你的系统里面其他团队开发的一个微服务,报错的信息是int 对象是不可读取索引的,这会让人很奇怪,2这个int对象明明是一个值,而不是用来查找索引数据的。 这时候程序的健壮性是比较差的,要想让程序保证健壮,我们可以使用 if-else 来判断每个键是否存在,就像这样 这里的三个if 看起来一点都不够优雅,如果其他地方也有同样的写法,只是键的顺序和名字不一样而已呢。能不能封装一个通用的函数来处理类似的情况呢? update_in Python支持面向过程、面向对象、函数式等多范式编程。我们可以使用函数式编程思想来达到这一点。先来看一个简单一点的 update_in 函数 from typing import Dict, List, T def update_in(data: Dict, ks: List, value: T): """Updates a value in a nested associative structure. Args: data (Dict): nested associative structure ks (List): sequence of keys value (Any): new value """ if len(ks) == 0: return cursor = data for k in ks[:-1]: if k not in cursor: cursor[k] = {} elif not isinstance(cursor[k], dict): cursor[k] = {} cursor = cursor[k] cursor[ks[-1]] = value 这里有一个类型 T ,这是Python内置的任意类型,在 typing 模块可以看到定义 T = TypeVar('T') ...

May 19, 2023

Python函数式编程之自定义函数get_in

Python函数式编程之 get_in 编程语言支持通过以下几种方式来解构具体问题: 大多数的编程语言都是 过程式 的,所谓程序就是一连串告诉计算机怎样处理程序输入的指令。C、Pascal 甚至 Unix shells 都是过程式语言。 在 声明式 语言中,你编写一个用来描述待解决问题的说明,并且这个语言的具体实现会指明怎样高效的进行计算。 SQL 可能是你最熟悉的声明式语言了。 一个 SQL 查询语句描述了你想要检索的数据集,并且 SQL 引擎会决定是扫描整张表还是使用索引,应该先执行哪些子句等等。 面向对象 程序会操作一组对象。 对象拥有内部状态,并能够以某种方式支持请求和修改这个内部状态的方法。Smalltalk 和 Java 都是面向对象的语言。 C++ 和 Python 支持面向对象编程,但并不强制使用面向对象特性。 函数式 编程则将一个问题分解成一系列函数。 理想情况下,函数只接受输入并输出结果,对一个给定的输入也不会有影响输出的内部状态。 著名的函数式语言有 ML 家族(Standard ML,Ocaml 以及其他变种)和 Haskell。 一些语言的设计者选择强调一种特定的编程方式。 这通常会让以不同的方式来编写程序变得困难。其他多范式语言则支持几种不同的编程方式。Lisp,C++ 和 Python 都是多范式语言;使用这些语言,你可以编写主要为过程式,面向对象或者函数式的程序和函数库。在大型程序中,不同的部分可能会采用不同的方式编写;比如 GUI 可能是面向对象的而处理逻辑则是过程式或者函数式。 在函数式程序里,输入会流经一系列函数。每个函数接受输入并输出结果。函数式风格反对使用带有副作用的函数,这些副作用会修改内部状态,或者引起一些无法体现在函数的返回值中的变化。完全不产生副作用的函数被称作“纯函数”。消除副作用意味着不能使用随程序运行而更新的数据结构;每个函数的输出必须只依赖于输入。 真实案例 上面是一些基本的理论,在实际的工作当中,经常会看到从一个多层嵌套的字典当中取一个值,会使用连续的下标,但是如果中间某个值并非一个字典,就会导致程序的运行时错误。而这种错误经常得等到代码上线之后才会被发现,开发的时候经常都是测试的正常数据。 例如: # 查询Elasticsearch,获得检索结果 resp = es_request("_search", dsl) # 从检索结果当中取出结果总数 total = resp["hits"]["total"]["value"] 上面的代码通常不会有问题,因为Elasticsearch的检索结果总是会包含 hits/total/value 这个值,如果没有结果,这个值就为0。但是,看看下面的动态取值: value = resp["data"]["aggs"][aggs_key]["value"] 这是在封装了Elasticsearch查询之后的结果,假设是一个叫search_service的微服务,如果aggs下的值为空,那么再取动态的 aggs_key 的值就会报 Key Error 的错误。 ...

May 2, 2023

如何通过Apache POI在Word当中添加引用(尾注、参考文献)

简介 Apache POI是一个用于读写Microsoft Office格式文件(如Word文档、Excel电子表格和PowerPoint演示文稿)的Java API。它是Apache软件基金会的一个开源项目,旨在提供一个易于使用的接口来处理Office文件。Apache POI支持各种Office文件格式,包括早期的二进制文件格式和新的XML文件格式。它提供了许多类和方法来读取、写入和操作Office文件,使得开发人员可以轻松地创建、修改和读取各种Office文件。Apache POI是Java开发人员的一个强大工具,可以帮助他们在Java应用程序中集成Office文件的处理功能。 ...

April 24, 2023

聊聊ChatGPT消息流回复原理

去年底以来ChatGPT已经火出天际,似乎奇点已经到来。前不久GPT-4发布的新闻更是把这人工智能推向了一个新的高潮。我们注意到,ChatGPT的回复是具有打字的效果,时不时还停顿一下,看起来你就像在跟一个具有智慧的人在聊天,时不时思索一下。 那么ChatGPT的回复效果是如何实现的呢,今天就来聊一聊其中的一种实现方式:Server-sent events。这是一种服务器向客户端主动推送消息的技术。 服务器向浏览器推送信息,最先想到的就是WebSocket了。除了 WebSocket,还有一种方法:Server-Sent Events(以下简称 SSE)。本文介绍它的用法以及一个可以运行的示例。 除了SSE和WebSocket以外,还有一种经常使用到的方法是轮询,客户端不断的向服务器端发起查询请求以获得实时数据信息。 下面是 WebSocket、轮询和 SSE 的功能对比: SSE 和轮询使用 HTTP 协议,现有的服务器软件都支持。WebSocket 是一个独立协议 SSE 相比 WebSocket 更加轻量,使用简单;WebSocket 使用相对复杂;轮询使用简单 SSE 默认支持断线重连,WebSocket 需要自己实现断线重连 SSE 一般只用来传送文本,二进制数据需要编码后传送,WebSocket 默认支持传送二进制数据 SSE 支持自定义发送的消息类型 WebSocket 支持双向推送消息,SSE 是单向的 轮询性能开销大、轮询时间久导致客户端及时更新数据 什么是SSE SSE是HTML 5规范的一个组成部分,是一种服务器推送技术,使客户端可以通过HTTP连接从服务器自动接收更新。使用server-sent events,服务器可以在任何时刻向我们的Web页面推送数据和信息。这些被推送进来的信息可以在这个页面上作为Events + data的形式来处理。 严格地说,HTTP 协议无法做到服务器主动推送信息,但是,服务器会向客户端发送响应的内容里面会声明,接下来会发送流信息(streaming),然后服务端就会不断的向客户发送数据流,直到结束。客户端在收到响应后会保持连接,持续的接收服务器发送过来的数据。 SSE 就是利用这种机制,使用流信息向浏览器推送信息。它基于 HTTP 协议,目前除了 IE,其他浏览器都支持。 各种浏览器支持情况可以查看Can I Use 举个栗子 下面我们使用Python及FastAPI框架,编写服务端代码。 服务端代码 import time import random from fastapi import FastAPI, Response from fastapi.responses import StreamingResponse app = FastAPI() async def fake_number_streamer(): for i in range(random.randint(10, 20)): yield "{}".format(i+1) time.sleep(0.1 * random.randint(1, 10)) @app.get("/") async def index(): # 读取html内容输出给客户端 return Response(open("index.html", encoding="utf-8").read()) @app.get("/sse") async def sse(): return StreamingResponse(fake_number_streamer(), media_type="text/event-stream") 服务端代码比较简单,首先需要安装fastapi (pip install fastapi)。然后需要定义一下生成器函数,用来模拟持续输出信息的逻辑,这里直接用一个随机数,输出从1开始,到10,20之间的随机数列。 ...

April 8, 2023

手把手教你用Python调用gpt-3.5-turbo复现ChatGPT

大家好,我是凯文。今天为大家介绍如何使用Python复刻ChatGPT的思路,以及核心代码。 预备知识 首先,Python的版本推荐是3.9。我们需要安装OpenAI的API,这可以通过使用pip install openai命令进行完成。接下来,我们需要在OpenAI的网站上注册并申请API密钥,这样我们才能开始使用它们的API(关于如何申请API密钥请另行搜索,或者联系我) 一旦我们有了API密钥,我们就可以从Python中使用OpenAI的API。具体来说,我们需要使用openai.ChatCompletion.create函数来生成对话响应。我们还需要使用GPT-3.5模型,这可以通过设置model参数为“gpt-3.5-turbo”来完成。 下面我们以一个命令行程序来演示整个核心逻辑。我们先来看流程图 流程图 flowchart LR CommandLine(接收命令行输入) --> ConstructMessages(组装消息) ConstructMessages --> CallOpenAIAPI(调用OpenAI的API接口) CallOpenAIAPI --> 输出对话内容 代码 我们先从如何调用OpenAI的API接口开始,使用自底向上的方法来开发我们的ChatGPT。 from dataclasses import dataclass from typing import List import openai MODEL = "gpt-3.5-turbo" TEMPERATURE = 0.5 openai.api_key = "YOUR API KEY" openai.proxy = "socks5h://127.0.0.1:1080" @dataclass class Prior: question: str answer: str 上面的代码首先引入三个模块,然后定义模型名称MODEL以及回答内容的创意性Temperature(说人话就是随机性,值的范围是0到2,值越大随机性越大). 接下来就是设置API Key了,如果你运行程序的电脑不能直接连接到openai的服务器,请设置proxy。 然后定义一下dataclass Prior,这个相当于保存历史记录用的,记录问题及答案文本内容。 下面来看chat函数: def chat(priors: List[Prior], question: str): messages = [] for prior in priors: messages.append({"role": "user", "content": prior.question}) messages.append({"role": "assistant", "content": prior.answer}) messages.append({"role": "user", "content": question}) resp = openai.ChatCompletion.create( model=MODEL, messages=messages, temperature=TEMPERATURE, stream=True ) return resp 接收一个priors列表,以及一个提问的文本question。函数前半部分组装messages参数,根据历史记录组装一个类似下面列表的列表: ...

April 2, 2023

Spring Boot 3集成Redis

Spring Boot 3真的很香,最大的改变可能就是GraalVM的支持了,直接可以打包成可以运行程序,把jre直接省掉了,性能得到了很好的提升。 但是升级完成后,集成Redis的时候直接傻眼了,一直报错,我们来看一下堆栈信息: org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to localhost/<unresolved>:6379 Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: localhost/127.0.0.1:6379 Caused by: java.net.ConnectException: Connection refused 再来看一下配置文件 application.yml spring: redis: host: redis port: 6379 password: 这里解释一下 host 设置为 redis 的原因,我是在 docker-compose.yml 配置的service和redis服务,在本地使用的 127.0.0.1 好好的,心想到线上改成docker compose容器的hostname就可以了。结果死活报连接出错。 推测 首先,推测是不是redis.conf没有配置允许所有外部机器连接。把redis.conf配置好之后,依然报错。 然后,推测是不是配置文件没有正确的映射到docker容器里面,进入到容器进行检查,配置没有问题。 最后,推测是不是spring data redis的默认LettuceConnectionFactory 连接没有读取到配置文件的内容,然后进行一番调试,发现如果不创建一个新的LettuceConnectionFactory 那么默认就会连接到 localhost:6379 上去。 调试 先找到类LettuceConnectionFactory 在所有的构造函数里面打上断点,调试一次后,发现还有一个LettuceConnectionConfiguration在前面进行配置的创建,方法如下: class LettuceConnectionConfiguration extends RedisConnectionConfiguration { private LettuceConnectionFactory createLettuceConnectionFactory(LettuceClientConfiguration clientConfiguration) { if (getSentinelConfig() != null) { return new LettuceConnectionFactory(getSentinelConfig(), clientConfiguration); } if (getClusterConfiguration() != null) { return new LettuceConnectionFactory(getClusterConfiguration(), clientConfiguration); } return new LettuceConnectionFactory(getStandaloneConfig(), clientConfiguration); } } 由于没有cluster配置,运行到了return new LettuceConnectionFactory(getStandaloneConfig(), clientConfiguration);这一行。 ...

March 19, 2023

使用ChatGPT在指定数据集上进行对话

ChatGPT不全面简介 ChatGPT是一种基于预训练的自然语言生成模型,是GPT系列模型的一种。ChatGPT的论文并没有公开发表,最相关的一篇工作就是InstructGPT(Training language models to follow instructions with human feedback)了,发表时间是2022年3月4日。 InstructGPT基于GPT-3.5来训练的,但是GPT-3.5官方并没有释放出来。InstructGPT是结合了RLHF(reinforcement learning from human feedback)(Christiano et al., 2017; Stiennon et al., 2020)—基于人工反馈的强化学习方法 — 训练出来的文本生成模型。 上面的图展示了InstractGPT训练的三个过程: 从prompt数据库当中采样prompt列表,通过人工标注,用于对GPT-3进行微调; 训练强化学习的奖励模型,采用的方法是输入prompt到多个模型,人工标注生成的内容的相关性;通过标注的相关性数据训练奖励模型; 使用奖励模型来优化InstructGPT models (PPO-ptx)。 在指定数据集上进行对话 什么意思呢?举个栗子,给定你一个文本文件,让ChatGPT根据给定的文本内容来回答你提出的问题。下面看一个具体的例子,我在阅读InstructGPT的论文的时候,英文不太好,摘要不想,就让ChatGPT告诉我摘要在讲什么,还得中文回答我: 看这个回答还是太长了,我得让他再精简一点,要求50个字讲清楚: 虽然对字段的精确理解还差了一些,但确实短了不少😄。 现在来讲一下大概的原理。GPT模型本身就是一个In-context learning的过程,可以根据给定的上下文,生成与上下文非常相关的内容。 有了这个原理,我们就有思路了,如果是一个给定的数据集,而不是一段文本呢?另外,还有一个信息非常重要,我们是使用OpenAI的官方API(gpt-3.5-turbo模型)来实现这个demo,OpenAI的API的token数量是有限制的,所以上下文的内容长度是有限制的。那么很明显了,需要把问题和问题相关的文本块要像上面那样去组织,然后丢给OpenAI的API来回答即可。 流程图 我们来画个流程图 分步骤实现 首先把准备的语料切分成文本块,官方给的例子是按句子进行切分,然后合并相邻的两个句子,如果合并后的长度在500个token以内就保留合并的内容,如果超过这个阈值就不合并。 def split_into_many(text, max_tokens=500): sentences = text.split('. ') n_tokens = [len(tokenizer.encode(" " + sentence)) for sentence in sentences] chunks = [] tokens_so_far = 0 chunk = [] for sentence, token in zip(sentences, n_tokens): if tokens_so_far + token > max_tokens: chunks.append(". ".join(chunk) + ".") chunk = [] tokens_so_far = 0 if token > max_tokens: continue chunk.append(sentence) tokens_so_far += token + 1 return chunks 这个split_into_many函数就是对一大段文本进行切分用的,按照. 分割文本,分割后以max_tokens为阈值进行合并。最后返回文本块数组。 ...

March 14, 2023

rsync的强大之处-不全面指南

介绍 rsync是一个强大的工具,已经存在了相当长的时间。它代表远程同步,用于在两个不同的系统之间同步文件和目录。它是一个流行的命令行实用程序,广泛用于备份和镜像目的。它也用于以安全和高效的方式在系统之间传输文件。rsync适用于大多数基于Unix的系统,包括Linux、macOS和BSD。 在这篇博客文章中,我们将探讨rsync的各种功能,以及如何使用它简化数据传输过程。我们还将看一些rsync的常见用例,以及它与其他用于数据传输的工具相比如何。 举个栗子最简单的rsync例子: 将本地文件夹/path/to/local/folder同步到远程服务器的/path/to/remote/folder: rsync -avz /path/to/local/folder user@remote:/path/to/remote/folder 该命令将本地文件夹的内容同步到远程服务器上的指定位置。这对于在本地进行更改并将更改传输到远程服务器上的情况非常有用。 rsync的使用场景 使用Rsync传输数据 rsync 是一个非常好用的工具,能够在两个系统之间传输数据。该工具使用增量传输算法,只传输两个文件之间的差异部分。这意味着只有文件中发生变化的部分会被传输,从而减少了需要传输的数据量。rsync 还可以用于通过 SSH 传输数据,这意味着在传输过程中数据是加密的,是一种安全的传输敏感数据的方式。 rsync有很多选项可以用来自定义传输过程。例如,您可以使用-v选项显示详细输出,以显示传输的进度。您还可以使用-P选项显示传输的进度,并在传输中断时恢复传输。rsync还可以传输具有不同权限和文件所有权的文件。 使用rsync备份数据 备份数据是确保重要文件不会因系统崩溃或其他问题而丢失的关键。rsync可用于将数据从一个系统备份到另一个系统。该工具可用于在远程系统上创建目录或文件的备份。rsync也可用于本地备份数据,这意味着将数据备份到外部硬盘或其他存储设备。 使用rsync进行备份的优点之一是可以用它来创建增量备份。这意味着只有自上次备份以来所做的更改才会被复制到备份位置。因此,备份更快,需要更少的存储空间。rsync还可以用于将数据备份到远程服务器,这意味着数据被备份到离线地点,并受到火灾、洪水和地震等灾难的保护。 我就是使用rsync命令来同步电脑与硬盘的备份,写一个bash脚本把想要同步的文件夹都写进去,一个命令就搞定了,以后妈妈再也不用担心我的数据丢失和不同步了。 如果你是Windows系统,请安装msys2工具,它提供了一个类似于Unix的环境,可以在其中使用rsync。msys2包含了一个包管理器,可以用于安装各种Unix工具和应用程序,如Git和Vim。因此,您可以在Windows系统上使用rsync和其他常用的Unix工具,而无需安装Linux或macOS等操作系统。 安装msys2非常简单,只需从其官方网站下载安装程序即可。安装完成后,您可以在msys2 shell中使用rsync和其他命令,如ls和cd。您可以使用pacman命令安装其他Unix工具和应用程序,如Git和Vim。msys2是在Windows系统上使用rsync的最佳选择之一,因为它提供了完整的Unix环境,可以满足大多数用户的需求。 使用 rsync 镜像数据 rsync也可以用于在两个系统之间镜像数据。镜像是将数据从一个系统复制到另一个系统的过程。rsync可以用于实时在两个系统之间镜像数据。这意味着在一个系统上对数据所做的任何更改都会自动镜像到另一个系统上。rsync是在系统之间镜像数据的高效方式,因为它只传输文件的更改部分。 使用Rsync进行镜像的一个优点是可以在不同的网络之间镜像数据。这意味着可以在不同地理位置的系统之间镜像数据。rsync还可以用于在拥有不同操作系统的系统之间镜像数据。例如,您可以使用rsync在Linux服务器和Windows工作站之间镜像数据。 rsync与其他工具比较 有许多其他工具可用于数据传输、备份和镜像。一些流行的工具包括SCP、FTP和SFTP。然而,rsync比这些工具有一些优势。例如,rsync比SCP和FTP更快,因为它只传输文件的更改部分。Rsync比FTP更安全,因为它可以用于通过SSH传输数据。最后,rsync比SFTP更灵活,因为它可以用于在具有不同操作系统的系统之间传输数据。 rsync使用举例 使用 rsync 的例子有很多,以下是一些示例: 将本地文件夹同步到远程服务器:rsync -avz /path/to/local/folder user@remote:/path/to/remote/folder。该命令将本地文件夹的内容同步到远程服务器上的指定位置。这对于在本地进行更改并将更改传输到远程服务器上的情况非常有用。 将远程服务器上的文件夹同步到本地:rsync -avz user@remote:/path/to/remote/folder /path/to/local/folder。该命令将远程服务器上的文件夹同步到本地指定位置。这对于从远程服务器获取最新数据并在本地进行操作的情况非常有用。 将本地文件夹备份到外部硬盘:rsync -avz /path/to/local/folder /path/to/external/drive。该命令将本地文件夹的内容备份到外部硬盘上的指定位置。这对于保护本地数据并避免因硬盘故障而造成数据丢失的情况非常有用。 将远程服务器上的文件夹备份到本地:rsync -avz user@remote:/path/to/remote/folder /path/to/local/folder。该命令将远程服务器上的文件夹备份到本地指定位置。这对于保护远程数据并避免因服务器故障而造成数据丢失的情况非常有用。 在两个系统之间同步文件夹:rsync -avz user@remote:/path/to/remote/folder user@local:/path/to/local/folder。该命令将远程服务器上的文件夹同步到本地指定位置。这对于在多个系统之间同步数据非常有用。 除了以上示例以外,rsync 还有很多选项可以用于自定义传输过程。例如,您可以使用--delete选项从目标中删除源中不存在的文件。您还可以使用--exclude选项从传输过程中排除某些文件或目录。使用这些选项可以帮助您更好地控制 rsync 的行为。 exclude参数 --exclude参数可用于从rsync传输过程中排除某些文件或目录。它的语法如下: rsync --exclude=PATTERN 其中,PATTERN是要从传输过程中排除的文件或目录的模式。模式可以是简单的字符串,也可以是正则表达式。例如,要从传输过程中排除所有以.log结尾的文件,可以使用以下命令: rsync --exclude='*.log' 要排除多个模式,请再次使用--exclude参数。例如,要排除所有以.log和.tmp结尾的文件,请使用以下命令: rsync --exclude='*.log' --exclude='*.tmp' ...

March 13, 2023

10行代码调用ChatGPT

OpenAI无疑是人工智能应用领域的领先者之一。该组织致力于研究人工智能的前沿技术,以及探索如何将这些技术应用于实际问题。它的研究和开发项目覆盖了广泛的领域,包括自动化、机器人、语音识别和自然语言处理等。 下面是OpenAI api首页列出的一些功能以及使用指南: 图1 OpenAI API首页 我们可以看到有Chat ,有文本生成,有基于向量的搜索、分类以及文本对比,有语音转文本,有图像生成,有代码生成,还有大模型的精调。其实还有很多很好玩的功能没有列出来,以后可以再写文章介绍更多的玩法。 这次咱们就来演示如何调用 Chat 的api实现类似ChatGPT的魔法。 OpenAI不仅宣布开放,价格还直接打了个骨折:0.002美元/每1000 token,仅为此前GPT-3.5(text-devinci-003)价格的1/10。ChatGPT API 质优价廉,开发者胖友们可以赶快用起来了。 下面就是示例代码,10行代码实现ChatGPT: import openai openai.api_key = "API_KEY" def ask_chatgpt(text): resp = openai.ChatCompletion.create( model="gpt-3.5-turbo", messages=[ {"role": "user", "content": text} ], temperature=0, ) return resp.choices[0].message 上面的11行Python代码实现了ChatGPT模型的调用,把temperature设置为0,可以让结果更加稳定,temperature最大值为1,值越大结果更不一样,如果想规避查重风险,直接把temperature参数值调到最大。 下面来对比一下gpt-3.5-turbo(ChatGPT/GPT-3.5)与text-devinci-003(GPT-3)的输出结果。以Java代码写快速排序为例: 图2 gpt-3.5-turbo的输出结果 图2 text-devinci-003的输出结果 可以很明显的看到gpt-3.5-turbo(ChatGPT/GPT-3.5)不仅输出了完整的代码(拷贝下来直接运行),还给出了代码的解释。 是不是更加香了,大家赶快用起来吧。

March 9, 2023