diff --git a/docSite/assets/docs/scss/custom/pages/_custom.scss b/docSite/assets/docs/scss/custom/pages/_custom.scss index 2fd8a7664..fe7b51d86 100644 --- a/docSite/assets/docs/scss/custom/pages/_custom.scss +++ b/docSite/assets/docs/scss/custom/pages/_custom.scss @@ -1,3 +1,16 @@ +:root { + --code-bg: rgba(0, 0, 0, 0.03); + --code-color: rgba(14, 116, 144, 0.95); + --inline-code-border: 0.5px solid var(--gray-400); + +} + +[data-dark-mode] { + --code-bg: hsla(0, 2%, 14%, 1); + --code-color: #f3f4f6ed; + --inline-code-border: 0.5px solid var(--gray-600); +} + #content { font-family: JetBrains Mono, LXGW WenKai Screen, -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica Neue", "Ubuntu"; } @@ -62,11 +75,33 @@ div.code-toolbar { z-index: 1; } +.docs-content .main-content pre code { + padding: 0 2.5rem 1.25rem .9rem; + } + +.docs-content .main-content code { + font-size: .875em; + padding: 1px 2px; + background: var(--code-bg); + border: var(--inline-code-border); + padding-top: 3px; + padding-bottom: 3px; + padding-left: 5px; + padding-right: 5px; + border-radius: .25rem; + color: var(--code-color); +} + li p { margin-top: 1rem !important; margin-bottom: 1rem; } +.docs-content .main-content ul > li { + margin-top: .3rem !important; + margin-bottom: .3rem; +} + footer { height: 118px !important; } diff --git a/docSite/assets/docs/scss/custom/plugins/prism/themes/_lotusdocs.scss b/docSite/assets/docs/scss/custom/plugins/prism/themes/_lotusdocs.scss new file mode 100644 index 000000000..e4e14e863 --- /dev/null +++ b/docSite/assets/docs/scss/custom/plugins/prism/themes/_lotusdocs.scss @@ -0,0 +1,178 @@ + /** + * Lotus Docs theme + * + * Adapted from a theme based on: + * https://github.com/chriskempson/tomorrow-theme + * + * @author Colin Wilson + * @version 1.0 + */ + + :root { + --prism-code-bg: #faf9f8; + --prism-code-scrollbar-thumb-color: var(--gray-400); + --prism-color: #333; + --prism-bg: #f0f0f0; + --prism-highlight-bg: var(--blue-200); + --prism-copy-bg: var(--gray-500); + --prism-copy-hover-bg: var(--gray-700); + --prism-copy-success-bg: var(--emerald-500); + --prism-token-punctuation: #666; + --prism-token-deleted: #2b6cb0; + --prism-token-function-name: #3182bd; + --prism-token-function: #c53030; + --prism-token-number: var(--cardinal-600); + --prism-token-symbol: #333; + --prism-token-builtin: #1a202c; + --prism-token-regex: #2f855a; + --prism-token-variable: var(--yellow-700); + --prism-token-url: #4fd1c5; + --prism-token-inserted: #38a169; +} + +[data-dark-mode] { + --prism-code-bg: var(--gray-900); + --prism-code-scrollbar-thumb-color: var(--gray-600); + --prism-color: #f5fbff; + --prism-bg: #32325d; + --prism-highlight-bg: var(--blue-400); + --prism-copy-bg: var(--gray-400); + --prism-copy-hover-bg: var(--white); + --prism-copy-success-bg: var(--emerald-200); + --prism-token-punctuation: #ccc; + --prism-token-deleted: #7fd3ed; + --prism-token-function-name: #6196cc; + --prism-token-function: #fda3f3; + --prism-token-number: var(--cardinal-200); + --prism-token-symbol: #ffffff; + --prism-token-builtin: #a4cdfe; + --prism-token-regex: #7ec699; + --prism-token-variable: var(--yellow-100); + --prism-token-url: #67cdcc; + --prism-token-inserted: green; +} + + code[class*="language-"], + pre[class*="language-"] { + color: var(--prism-color) !important; + background: var(--prism-code-bg) !important; + } + +/* Code blocks */ +pre[class*="language-"] { + // padding: 1em; + // margin: .5em 0; + overflow: auto; + border-radius: 0 0 4px 4px; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: var(--prism-bg); +} + +/* Inline code */ +:not(pre) > code[class*="language-"] { + padding: .1em; + border-radius: .3em; + white-space: normal; +} + +.line-highlight:before, +.line-highlight[data-end]:after { + background-color: var(--prism-highlight-bg); +} + +[data-copy-state="copy"] span:empty::before { + background-color: var(--prism-copy-bg); +} + +[data-copy-state="copy"] span:empty:hover::before { + background-color: var(--prism-copy-hover-bg); +} + +[data-copy-state="copy-success"] span:empty::before { + background-color: var(--prism-copy-success-bg); +} + +.token.comment, +.token.block-comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: #999; +} + +.token.punctuation { + color: var(--prism-token-punctuation); +} + +.token.tag, +.token.attr-name, +.token.namespace, +.token.deleted { + color: var(--prism-token-deleted); +} + +.token.function-name { + color: var(--prism-token-function-name); +} + +.token.boolean, +.token.function { + color: var(--prism-token-function); +} + +.token.number { + color: var(--prism-token-number); +} + +.token.property, +.token.class-name, +.token.constant, +.token.symbol { + color: var(--prism-token-symbol); + font-weight: 700; +} + +.token.selector, +.token.important, +.token.atrule, +.token.keyword, +.token.builtin { + color: var(--prism-token-builtin); + font-weight: 700; +} + +.token.string, +.token.char, +.token.attr-value, +.token.regex { + color: var(--prism-token-regex); +} + +.token.variable { + color: var(--prism-token-variable); +} + +.token.operator, +.token.entity, +.token.url { + color: var(--prism-token-url); +} + +.token.important, +.token.bold { + font-weight: bold; +} +.token.italic { + font-style: italic; +} + +.token.entity { + cursor: help; +} + +.token.inserted { + color: var(--prism-token-inserted); +} \ No newline at end of file diff --git a/docSite/assets/imgs/fastgpt-list-models.png b/docSite/assets/imgs/fastgpt-list-models.png new file mode 100644 index 000000000..0edaf7b12 Binary files /dev/null and b/docSite/assets/imgs/fastgpt-list-models.png differ diff --git a/docSite/assets/imgs/one-api-add-xinference-models.jpg b/docSite/assets/imgs/one-api-add-xinference-models.jpg new file mode 100644 index 000000000..cae191d85 Binary files /dev/null and b/docSite/assets/imgs/one-api-add-xinference-models.jpg differ diff --git a/docSite/assets/imgs/xinference-launch-model.png b/docSite/assets/imgs/xinference-launch-model.png new file mode 100644 index 000000000..1e0e26953 Binary files /dev/null and b/docSite/assets/imgs/xinference-launch-model.png differ diff --git a/docSite/content/docs/development/custom-models/bge-rerank.md b/docSite/content/docs/development/custom-models/bge-rerank.md index d68aa0486..3fc87cd43 100644 --- a/docSite/content/docs/development/custom-models/bge-rerank.md +++ b/docSite/content/docs/development/custom-models/bge-rerank.md @@ -4,7 +4,7 @@ description: '接入 bge-rerank 重排模型' icon: 'sort' draft: false toc: true -weight: 910 +weight: 920 --- ## 不同模型推荐配置 diff --git a/docSite/content/docs/development/custom-models/chatglm2-m3e.md b/docSite/content/docs/development/custom-models/chatglm2-m3e.md index 4c169e2de..775562d84 100644 --- a/docSite/content/docs/development/custom-models/chatglm2-m3e.md +++ b/docSite/content/docs/development/custom-models/chatglm2-m3e.md @@ -4,7 +4,7 @@ description: ' 将 FastGPT 接入私有化模型 ChatGLM2和m3e-large' icon: 'model_training' draft: false toc: true -weight: 930 +weight: 950 --- ## 前言 diff --git a/docSite/content/docs/development/custom-models/chatglm2.md b/docSite/content/docs/development/custom-models/chatglm2.md index a35c7bdea..fcdb74f29 100644 --- a/docSite/content/docs/development/custom-models/chatglm2.md +++ b/docSite/content/docs/development/custom-models/chatglm2.md @@ -4,7 +4,7 @@ description: ' 将 FastGPT 接入私有化模型 ChatGLM2-6B' icon: 'model_training' draft: false toc: true -weight: 910 +weight: 930 --- ## 前言 diff --git a/docSite/content/docs/development/custom-models/m3e.md b/docSite/content/docs/development/custom-models/m3e.md index 1d9d2a992..63497e734 100644 --- a/docSite/content/docs/development/custom-models/m3e.md +++ b/docSite/content/docs/development/custom-models/m3e.md @@ -4,7 +4,7 @@ description: ' 将 FastGPT 接入私有化模型 M3E' icon: 'model_training' draft: false toc: true -weight: 920 +weight: 940 --- ## 前言 diff --git a/docSite/content/docs/development/custom-models/xinference.md b/docSite/content/docs/development/custom-models/xinference.md new file mode 100644 index 000000000..73a46a262 --- /dev/null +++ b/docSite/content/docs/development/custom-models/xinference.md @@ -0,0 +1,184 @@ +--- +title: '使用 Xinference 接入本地模型' +description: '一站式本地 LLM 私有化部署' +icon: 'api' +draft: false +toc: true +weight: 910 +--- + +[Xinference](https://github.com/xorbitsai/inference) 是一款开源模型推理平台,除了支持 LLM,它还可以部署 Embedding 和 ReRank 模型,这在企业级 RAG 构建中非常关键。同时,Xinference 还提供 Function Calling 等高级功能。还支持分布式部署,也就是说,随着未来应用调用量的增长,它可以进行水平扩展。 + +## 安装 Xinference + +Xinference 支持多种推理引擎作为后端,以满足不同场景下部署大模型的需要,下面会分使用场景来介绍一下这三种推理后端,以及他们的使用方法。 + +### 1. 服务器 + +如果你的目标是在一台 Linux 或者 Window 服务器上部署大模型,可以选择 Transformers 或 vLLM 作为 Xinference 的推理后端: + ++ [Transformers](https://huggingface.co/docs/transformers/index):通过集成 Huggingface 的 Transformers 库作为后端,Xinference 可以最快地 集成当今自然语言处理(NLP)领域的最前沿模型(自然也包括 LLM)。 ++ [vLLM](https://vllm.ai/): vLLM 是由加州大学伯克利分校开发的一个开源库,专为高效服务大型语言模型(LLM)而设计。它引入了 PagedAttention 算法, 通过有效管理注意力键和值来改善内存管理,吞吐量能够达到 Transformers 的 24 倍,因此 vLLM 适合在生产环境中使用,应对高并发的用户访问。 + +假设你服务器配备 NVIDIA 显卡,可以参考[这篇文章中的指令来安装 CUDA](https://xorbits.cn/blogs/langchain-streamlit-doc-chat),从而让 Xinference 最大限度地利用显卡的加速功能。 + +#### Docker 部署 + +你可以使用 Xinference 官方的 Docker 镜像来一键安装和启动 Xinference 服务(确保你的机器上已经安装了 Docker),命令如下: + +```bash +docker run -p 9997:9997 --gpus all xprobe/xinference:latest xinference-local -H 0.0.0.0 +``` + +#### 直接部署 + +首先我们需要准备一个 3.9 以上的 Python 环境运行来 Xinference,建议先根据 conda 官网文档安装 conda。 然后使用以下命令来创建 3.11 的 Python 环境: + +```bash +conda create --name py311 python=3.11 +conda activate py311 +``` + +以下两条命令在安装 Xinference 时,将安装 Transformers 和 vLLM 作为 Xinference 的推理引擎后端: + +```bash +pip install "xinference[transformers]" +pip install "xinference[vllm]" +pip install "xinference[transformers,vllm]" # 同时安装 +``` + +PyPi 在 安装 Transformers 和 vLLM 时会自动安装 PyTorch,但自动安装的 CUDA 版本可能与你的环境不匹配,此时你可以根据 PyTorch 官网中的[安装指南](https://pytorch.org/get-started/locally/)来手动安装。 + +只需要输入如下命令,就可以在服务上启动 Xinference 服务: + +```bash +xinference-local -H 0.0.0.0 +``` + +Xinference 默认会在本地启动服务,端口默认为 9997。因为这里配置了-H 0.0.0.0参数,非本地客户端也可以通过机器的 IP 地址来访问 Xinference 服务。 + +### 2. 个人设备 + +如果你想在自己的 Macbook 或者个人电脑上部署大模型,推荐安装 CTransformers 作为 Xinference 的推理后端。CTransformers 是用 GGML 实现的 C++ 版本 Transformers。 + +[GGML](https://ggml.ai/) 是一个能让大语言模型在[消费级硬件上运行](https://github.com/ggerganov/llama.cpp/discussions/205)的 C++ 库。 GGML 最大的特色在于模型量化。量化一个大语言模型其实就是降低权重表示精度的过程,从而减少使用模型所需的资源。 例如,表示一个高精度浮点数(例如 0.0001)比表示一个低精度浮点数(例如 0.1)需要更多空间。由于 LLM 在推理时需要加载到内存中的,因此你需要花费硬盘空间来存储它们,并且在执行期间有足够大的 RAM 来加载它们,GGML 支持许多不同的量化策略,每种策略在效率和性能之间提供不同的权衡。 + +通过以下命令来安装 CTransformers 作为 Xinference 的推理后端: + +```bash +pip install xinference +pip install ctransformers +``` + +因为 GGML 是一个 C++ 库,Xinference 通过 `llama-cpp-python` 这个库来实现语言绑定。对于不同的硬件平台,我们需要使用不同的编译参数来安装: + +- Apple Metal(MPS):`CMAKE_ARGS="-DLLAMA_METAL=on" pip install llama-cpp-python` +- Nvidia GPU:`CMAKE_ARGS="-DLLAMA_CUBLAS=on" pip install llama-cpp-python` +- AMD GPU:`CMAKE_ARGS="-DLLAMA_HIPBLAS=on" pip install llama-cpp-python` + +安装后只需要输入 `xinference-local`,就可以在你的 Mac 上启动 Xinference 服务。 + +## 创建并部署模型(以 Qwen-14B 模型为例) + +### 1. WebUI 方式启动模型 + +Xinference 启动之后,在浏览器中输入: `http://127.0.0.1:9997`,我们可以访问到本地 Xinference 的 Web UI。 + +打开“Launch Model”标签,搜索到 qwen-chat,选择模型启动的相关参数,然后点击模型卡片左下方的小火箭🚀按钮,就可以部署该模型到 Xinference。 默认 Model UID 是 qwen-chat(后续通过将通过这个 ID 来访问模型)。 + +![](/imgs/xinference-launch-model.png) + +当你第一次启动 Qwen 模型时,Xinference 会从 HuggingFace 下载模型参数,大概需要几分钟的时间。Xinference 将模型文件缓存在本地,这样之后启动时就不需要重新下载了。 Xinference 还支持从其他模型站点下载模型文件,例如 [modelscope](https://inference.readthedocs.io/en/latest/models/sources/sources.html)。 + +### 2. 命令行方式启动模型 + +我们也可以使用 Xinference 的命令行工具来启动模型,默认 Model UID 是 qwen-chat(后续通过将通过这个 ID 来访问模型)。 + +```bash +xinference launch -n qwen-chat -s 14 -f pytorch +``` + +除了 WebUI 和命令行工具, Xinference 还提供了 Python SDK 和 RESTful API 等多种交互方式, 更多用法可以参考 [Xinference 官方文档](https://inference.readthedocs.io/en/latest/getting_started/index.html)。 + +## 将本地模型接入 One API + +One API 的部署和接入请参考[这里](/docs/development/one-api/)。 + +为 qwen1.5-chat 添加一个渠道,这里的 Base URL 需要填 Xinference 服务的端点,并且注册 qwen-chat (模型的 UID) 。 + +![](/imgs/one-api-add-xinference-models.jpg) + +可以使用以下命令进行测试: + +```bash +curl --location --request POST 'https:///v1/chat/completions' \ +--header 'Authorization: Bearer ' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "model": "qwen-chat", + "messages": [{"role": "user", "content": "Hello!"}] +}' +``` + +将 替换为你的 One API 地址, 替换为你的 One API 令牌。model 为刚刚在 One API 填写的自定义模型。 + +## 将本地模型接入 FastGPT + +修改 FastGPT 的 `config.json` 配置文件,其中 chatModels(对话模型)用于聊天对话,cqModels(问题分类模型)用来对问题进行分类,extractModels(内容提取模型)则用来进行工具选择。我们分别在 chatModels、cqModels 和 extractModels 中加入 qwen-chat 模型: + +```json +{ + "chatModels": [ + ... + { + "model": "qwen-chat", + "name": "Qwen", + "maxContext": 2048, + "maxResponse": 2048, + "quoteMaxToken": 2000, + "maxTemperature": 1, + "vision": false, + "defaultSystemChatPrompt": "" + } + ... + ], + "cqModels": [ + ... + { + "model": "qwen-chat", + "name": "Qwen", + "maxContext": 2048, + "maxResponse": 2048, + "inputPrice": 0, + "outputPrice": 0, + "toolChoice": true, + "functionPrompt": "" + } + ... + ], + "extractModels": [ + ... + { + "model": "qwen-chat", + "name": "Qwen", + "maxContext": 2048, + "maxResponse": 2048, + "inputPrice": 0, + "outputPrice": 0, + "toolChoice": true, + "functionPrompt": "" + } + ... + ] +} +``` + +然后重启 FastGPT 就可以在应用配置中选择 Qwen 模型进行对话: + +![](/imgs/fastgpt-list-models.png) + +--- + ++ 参考:[FastGPT + Xinference:一站式本地 LLM 私有化部署和应用开发](https://xorbits.cn/blogs/fastgpt-weather-chat) + + diff --git a/docSite/content/docs/development/one-api.md b/docSite/content/docs/development/one-api.md index eae82d2e2..51a3dfcf4 100644 --- a/docSite/content/docs/development/one-api.md +++ b/docSite/content/docs/development/one-api.md @@ -1,7 +1,7 @@ --- -title: '部署和使用OneAPI,实现Azure、ChatGLM、本地模型接入' -description: '部署和使用OneAPI,实现Azure、ChatGLM、本地模型接入。OneAPI使用教程' -icon: 'Api' +title: '使用 One API 接入 Azure、ChatGLM 和本地模型' +description: '部署和使用 One API,实现 Azure、ChatGLM 和本地模型的接入。' +icon: 'api' draft: false toc: true weight: 708 @@ -9,19 +9,19 @@ weight: 708 * 默认情况下,FastGPT 只配置了 GPT 的模型,如果你需要接入其他模型,需要进行一些额外配置。 * [One API](https://github.com/songquanpeng/one-api) 是一个 OpenAI 接口管理 & 分发系统,可以通过标准的 OpenAI API 格式访问所有的大模型,开箱即用。 -* FastGPT 可以通过接入 OneAPI 来实现对不同大模型的支持。OneAPI 的部署方法也很简单。 +* FastGPT 可以通过接入 One API 来实现对不同大模型的支持。One API 的部署方法也很简单。 -## FastGPT 与 OneAPI 关系 +## FastGPT 与 One API 关系 -可以把 OneAPI 当做一个网关。 +可以把 One API 当做一个网关。 ![](/imgs/sealos-fastgpt.webp) ## 部署 -### docker 版本 +### Docker 版本 -已加入最新的`docker-compose.yml`文件中。 +已加入最新的 `docker-compose.yml` 文件中。 ### Sealos - MySQL 版本 @@ -62,21 +62,21 @@ BATCH_UPDATE_ENABLED=true BATCH_UPDATE_INTERVAL=60 ``` -## One API使用教程 +## One API 使用教程 ### 概念 1. 渠道: 1. OneApi 中一个渠道对应一个 `Api Key`,这个 `Api Key` 可以是GPT、微软、ChatGLM、文心一言的。一个`Api Key`通常可以调用同一个厂商的多个模型。 - 2. OneAPI 会根据请求传入的`模型`来决定使用哪一个`Key`,如果一个模型对应了多个`Key`,则会随机调用。 -2. 令牌:访问 OneAPI 所需的凭证,只需要这`1`个凭证即可访问`OneAPI`上配置的模型。因此`FastGPT`中,只需要配置`OneAPI`的`baseurl`和`令牌`即可。 + 2. One API 会根据请求传入的`模型`来决定使用哪一个`Key`,如果一个模型对应了多个`Key`,则会随机调用。 +2. 令牌:访问 One API 所需的凭证,只需要这`1`个凭证即可访问`One API`上配置的模型。因此`FastGPT`中,只需要配置`One API`的`baseurl`和`令牌`即可。 ### 大致工作流程 -1. 客户端请求 OneAPI +1. 客户端请求 One API 2. 根据请求中的 `model` 参数,匹配对应的渠道(根据渠道里的模型进行匹配,必须完全一致)。如果匹配到多个渠道,则随机选择一个(同优先级)。 -3. OneAPI 向真正的地址发出请求。 -4. OneAPI 将结果返回给客户端。 +3. One API 向真正的地址发出请求。 +4. One API 将结果返回给客户端。 ### 1. 登录 One API @@ -96,7 +96,7 @@ BATCH_UPDATE_INTERVAL=60 ### 3. 修改账号余额 -OneAPI 默认 root 用户只有 200刀,可以自行修改编辑。 +One API 默认 root 用户只有 200刀,可以自行修改编辑。 ### 4. 修改 FastGPT 的环境变量 diff --git a/docSite/content/docs/pricing.md b/docSite/content/docs/pricing.md index f6daea4b3..6dd146946 100644 --- a/docSite/content/docs/pricing.md +++ b/docSite/content/docs/pricing.md @@ -5,6 +5,8 @@ icon: 'currency_yen' draft: false toc: true weight: 1200 +type: redirect +target: https://cloud.fastgpt.in/price --- -线上版价格请查看:https://cloud.fastgpt.in/price \ No newline at end of file +线上版价格请查看:[https://cloud.fastgpt.in/price](https://cloud.fastgpt.in/price) \ No newline at end of file diff --git a/docSite/layouts/redirect/single.html b/docSite/layouts/redirect/single.html new file mode 100644 index 000000000..fed5e5617 --- /dev/null +++ b/docSite/layouts/redirect/single.html @@ -0,0 +1 @@ +{{- template "_internal/alias.html" (dict "Permalink" .Params.target) -}} \ No newline at end of file