From 6983db9f282cd266f055221cc1686629d8f37cfe Mon Sep 17 00:00:00 2001 From: "yuxin.wang" Date: Fri, 17 Nov 2023 19:11:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=99=E7=A8=8B=20(#9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 添加教程 --------- Co-authored-by: wangyuxin --- README.md | 7 +- examples/advanced_usage.ipynb | 20 ++ examples/readme.md | 1 + examples/tutorial.ipynb | 435 ++++++++++++++++++++++++++++++++++ generate/version.py | 2 +- pyproject.toml | 2 +- 6 files changed, 464 insertions(+), 3 deletions(-) create mode 100644 examples/advanced_usage.ipynb create mode 100644 examples/readme.md create mode 100644 examples/tutorial.ipynb diff --git a/README.md b/README.md index f7ea2aa..006262d 100644 --- a/README.md +++ b/README.md @@ -19,14 +19,19 @@ Generate Package 允许用户通过统一的 api 访问跨平台的生成式模 ## Features * **多模态**,支持文本生成,图像生成以及语音生成 -* **跨平台**,支持 OpenAI,Azure,Minimax 在内的多家平台 +* **跨平台**,完整支持 OpenAI,Azure,Minimax 在内的多家平台, * **One API**,统一了不同平台的消息格式,推理参数,接口封装,返回解析 * **异步和流式**,提供流式调用,非流式调用,同步调用,异步调用,适配不同的应用场景 * **自带电池**,提供输入检查,参数检查,计费,*ChatEngine*, *CompletionEngine*, *function* 等功能 * **高质量代码**,100% typehints,pylance strict, ruff lint & format, test coverage > 85% ... +> 完整支持是指,只要是平台提供的功能和参数,`generate` 包都原生支持,不打折扣!比如,OpenAI 的 Function Call, Tool Calls,MinimaxPro 的 Plugins 等 ## 基础使用 + + Open In Colab + + ### 安装 ```bash diff --git a/examples/advanced_usage.ipynb b/examples/advanced_usage.ipynb new file mode 100644 index 0000000..5fa6f7a --- /dev/null +++ b/examples/advanced_usage.ipynb @@ -0,0 +1,20 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "🚧 施工中" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/readme.md b/examples/readme.md new file mode 100644 index 0000000..9050291 --- /dev/null +++ b/examples/readme.md @@ -0,0 +1 @@ +🚧 施工中 \ No newline at end of file diff --git a/examples/tutorial.ipynb b/examples/tutorial.ipynb new file mode 100644 index 0000000..3faf0c4 --- /dev/null +++ b/examples/tutorial.ipynb @@ -0,0 +1,435 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Generate\n", + "\n", + "👏🏻 欢迎来到 Generate 的教程,在这里您将学习到:\n", + "\n", + "1. 使用统一简洁的 API 替代不同平台杂乱的 SDK\n", + "2. 使用 `Generate` 生成文本,图像以及音频" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 做点小小的准备工作" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 安装" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# 第一步,安装 `generate-core` 😉\n", + "!pip install generate-core\n", + "# 顺便安装一下 rich 美化输出\n", + "!pip install rich " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`generate-core` 已经安装完成了,让我们看看能不能正确的引用 `generate` 包" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " import generate\n", + " import rich\n", + "except ImportError as e:\n", + " raise ValueError(\"没有执行 !pip install generate-core 和 rich 吗?\") from e\n", + "else:\n", + " print(\"一切都在计划之内,安装成功!\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 配置 OpenAI Key\n", + "\n", + "在使用 `generate` 之前,需要先配置 OpenAI API Key,这样才能使用 OpenAI 的 API。 \n", + "\n", + "`generate` 库使用 [Pydantic Settings](https://docs.pydantic.dev/latest/concepts/pydantic_settings/) 管理不同平台的配置,Pydantic Settings 会从 `.env` 文件,环境变量或者 **运行时** 获取相关配置。\n", + "\n", + "不过,我们先不管这么多,就先通过环境变量来完成配置吧!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "\n", + "os.environ['OPENAI_API_KEY'] = 'sk-*****'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "现在让我们测试一下配置是否生效" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from generate.platforms import OpenAISettings\n", + "from pydantic import ValidationError\n", + "\n", + "try:\n", + " OpenAISettings() # type: ignore\n", + "except ValidationError as e:\n", + " raise ValueError(\"没有设置 OPENAI_API_KEY 环境变量吗?\") from e\n", + "else:\n", + " print(\"好的!热身完毕,一切准备就绪,下面让我们正式开始 🚀!\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## ChatCompletion 文本生成\n", + "\n", + "在 `generate` 库中,无论是文本生成,图像生成,还是语音生成。他们遵循的都是相同的使用逻辑\n", + "1. 初始化生成模型\n", + " - [可选] 选择模型型号\n", + " - [可选] 设置默认的模型参数\n", + "2. 使用 `generate` 方法来调用模型\n", + " - [必选] 设置 prompt, 对于 ChatCompletion 来说,prompt 一般就是文本\n", + " - [可选] 设置此次调用的模型参数\n", + "3. 获取模型输出" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 基础使用\n", + "最简单的使用方式就是像下面这样,只控制 prompt,其他都使用默认值" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from generate import OpenAIChat\n", + "\n", + "model = OpenAIChat()\n", + "model_output = model.generate('你好,请介绍一下你自己')\n", + "\n", + "rich.print(model_output)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "我们可以看到模型输出了一个结构化的对象 `ChatCompletionOutput`,其中包括了一些有用的信息,比如:\n", + "- 模型信息,在 model_info 字段中,包含了任务种类,平台以及模型名称\n", + "- 生成消息,在 messages 字段中,包含了 gpt 模型生成的消息\n", + "- 计费信息,在 cost 字段中,包含了此次任务的花销,单位是元\n", + "- 结束原因,在 finish_reason 字段中,展示了此次任务完成的原因\n", + "- 额外信息,在 extra 字段中,包含了一些可能会有用的额外信息,比如此次任务使用了多少 token 等" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`ChatCompletionOutput` 对象的基类是 [Pydantic BaseModel](https://docs.pydantic.dev/latest/concepts/models/),因此我们可以通过访问属性的方式访问这些字段。\n", + "\n", + "除此之外,`ChatCompletionOutput` 还提供了一些常用的计算属性,比如 `reply` 和 `last_message`。就像下面这样" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "cost = model_output.cost\n", + "reply = model_output.reply\n", + "last_message = model_output.last_message\n", + "rich.print(f'{cost=}')\n", + "rich.print(f'{reply=}')\n", + "rich.print(f'{last_message=}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 设置模型及其参数\n", + "\n", + "当然,我们也可以不使用默认的模型和参数,而是自定义他们。\n", + "\n", + "模型的参数可以在模型初始化的时候设置,以作为模型的默认参数。也可以在调用 `generate` 方法的时候设置,以作为此次调用的参数。\n", + "\n", + "- 初始化时的参数,必须显式声明,以 `OpenAIChat` 为例,它的参数为 `OpenAIChatParameters` 实例。\n", + "- 调用时的参数,无须显式声明,直接传入关键字参数即可,比如 `model.generate('你好', temperature=0.5)`\n", + " \n", + "`generate` 包中的命名遵循固定的原则,任何模型参数的类名,都是模型名称 + Parameters\n", + "- OpenAIChat -> OpenAIChatParameters\n", + "- MinimaxChat -> MinimaxChatParameters" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from generate import OpenAIChat, OpenAIChatParameters\n", + "\n", + "\n", + "model_parameters = OpenAIChatParameters(top_p=0.85) # 显式声明模型参数\n", + "model = OpenAIChat(model='gpt-4', parameters=model_parameters) # 使用 GPT-4 模型\n", + "model_output = model.generate('你好', temperature=0.9) # 调用时传入 temperature 参数\n", + "rich.print(model_output)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 流式输出\n", + "\n", + "在 `generate` 方法前加上 stream,也就是 `stream_generate` ,就变成了流式输出!`stream_generate` 返回一个生产器,你可以通过 for 循环来迭代它。" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "stream_output = next(model.stream_generate('你好'))\n", + "rich.print(stream_output)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "yield 的对象是 `ChatCompletionStreamOutput`,它只是在 `ChatCompletionOutput` 的基础上增加了一个 stream 字段,其中 delta 代表每次生产的小片段,control 标识了控制信息。\n", + "\n", + "现在让我们完整的看一下流式输出的例子吧!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "model = OpenAIChat()\n", + "finish_output = None\n", + "for output in model.stream_generate('介绍一下三体中的主要人物'):\n", + " print(output.stream.delta, flush=True, end='')\n", + " if output.stream.control == 'finish':\n", + " finish_output = output\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rich.print(finish_output)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "我们可以看到,control 为 finish 的 `ChatCompletionStreamOutput` 中依然包含了各种有用的信息!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 多轮对话\n", + "\n", + "\n", + "上面介绍的例子都是单轮对话,而且也只涉及到文本,并不涉及到 FunctionCall,多模态对话等。\n", + "\n", + "这部分的内容将在进阶使用中详细介绍,下面我们只给一个简单的例子。" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "output = model.generate(\n", + " [\n", + " {'role': 'user', 'content': '你好,GPT!'},\n", + " {'role': 'assistant', 'content': '你好!有什么可以帮助你的吗?'},\n", + " {'role': 'user', 'content': '重复我的第一句话'},\n", + " ]\n", + ")\n", + "output.reply" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 输入及参数检查\n", + "\n", + "`generate` 包会对你指定的模型参数进行提前检查\n", + "\n", + "temperature 参数的取值范围是 0 到 1,如果你传入了一个不合法的值,那么 `generate` 会抛出一个异常,并告诉你 temperature 参数的取值范围" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "model.generate('你好', temperature=2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "恭喜 🎉,你已经学会了 OpenAIChat 的基础使用。\n", + "\n", + "掌握了 OpenAIChat 后,你也同样掌握了 `generate` 支持的所有聊天模型,他们的使用方式一模一样!\n", + "\n", + "让我们看看,你的工具箱里面还有哪些武器吧~" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from generate.chat_completion import ChatModels\n", + "\n", + "model_names = [model.__name__ for model, _ in ChatModels]\n", + "\n", + "print(f'以下的模型都可以通过和 OpenAIChat 一样的方式使用:')\n", + "print(model_names)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### One More Thing\n", + "\n", + "\n", + "除了 `generate.chat_completion` 模型外,`generate` 还支持 `generate.image_generation` 和 `generate.text_to_speech` 模型。\n", + "\n", + "\n", + "而且,他们的使用方式也和 `generate.chat_completion` 一模一样!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from IPython.display import Audio, Image\n", + "from generate import OpenAISpeech\n", + "\n", + "model = OpenAISpeech()\n", + "speech_output = model.generate('你好,世界!')\n", + "Audio(speech_output.audio)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from generate import OpenAIImageGeneration\n", + "\n", + "model = OpenAIImageGeneration(model='dall-e-2')\n", + "image_output = model.generate('一只可爱的猫')\n", + "Image(image_output.images[0].content)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "基础使用教程已经结束啦!🌟 如果你想深入了解更多精彩内容,可以继续探索我们的进阶使用教程、丰富的应用示例,或者深入阅读 `Generate` 文档!\n", + "\n", + "👩‍💻 对于以下议题感兴趣的朋友,请参考我们的[进阶使用教程](https://colab.research.google.com/github/wangyuxinwhy/generate/blob/main/examples/advanced_usage.ipynb):\n", + "1. 异步调用 `model.async_generate` 和异步流式调用 `model.async_stream_generate`\n", + "2. 设定灵活的重试策略 \n", + "3. 探索 gpt-4 支持的多模态对话功能\n", + "4. 了解 FunctionCall 与 ToolCalls\n", + "5. 熟悉有状态的对话引擎 `generate.ChatEngine`\n", + "6. 学习适用于大规模请求的补全引擎 `generate.CompletionEngine`\n", + "7. 更多精彩内容等你发现...\n", + "\n", + "🤖 同时,如果你对以下应用示例感兴趣,请不要错过我们的[应用示例](https://github.com/wangyuxinwhy/generate/tree/main/examples):\n", + "1. 🚧 代码解释器\n", + "2. 🚧 多模态聊天机器人\n", + "3. 🚧 网络文学多角色配音体验\n", + "\n", + "🔧 最后,如果你想了解如何配置其他大模型平台,或者全面系统地学习 `Generate`,请参考 [Generate 文档](https://wangyuxinwhy.github.io/generate/)\n", + "\n", + "祝你探索愉快!🚀💡" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "generate", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.18" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/generate/version.py b/generate/version.py index b794fd4..df9144c 100644 --- a/generate/version.py +++ b/generate/version.py @@ -1 +1 @@ -__version__ = '0.1.0' +__version__ = '0.1.1' diff --git a/pyproject.toml b/pyproject.toml index 2f3900b..78282eb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "generate-core" -version = "0.1.0" +version = "0.1.1" description = "文本生成,图像生成,语音生成" authors = ["wangyuxin "] license = "MIT"