Skip to content

07 ‐ 扩展

Touch-Night edited this page Aug 1, 2024 · 2 revisions

扩展

扩展由位于 text-generation-webui/extensions 子文件夹中名为 script.py 的文件定义。如果在 --extensions 命令行参数后指定了文件夹名称,这些扩展将在启动时加载。

例如,使用 python server.py --extensions silero_tts 可以加载 extensions/silero_tts/script.py

上述仓库包含用户扩展的目录。

如果你创建了一个扩展,欢迎将其托管在 GitHub 仓库中,并提交 PR 将其添加到列表中。

内置扩展

扩展 描述
openai 创建一个模仿 OpenAI API 的 API,可用作替代品。
multimodal 添加多模态支持(文本+图像)。详细描述请参阅扩展目录中的 README.md
google_translate 使用谷歌翻译自动翻译输入和输出。
silero_tts 使用 Silero 的文本转语音扩展。在聊天模式下使用时,回复会被替换为音频小组件。
whisper_stt 允许你在聊天模式下使用麦克风输入。
sd_api_pictures 允许你在聊天模式下向机器人请求图片,这些图片将使用 AUTOMATIC1111 Stable Diffusion API 生成。示例请参见这里
character_bias 一个非常简单的示例,在聊天模式下在机器人回复的开头添加一个隐藏字符串。
send_pictures 创建一个图片上传字段,可用于在聊天模式下向机器人发送图片。使用 BLIP 自动生成图片说明。
gallery 创建一个包含聊天角色及其图片的图库。
superbooga 一个使用 ChromaDB 创建任意大小伪上下文的扩展,可接受文本文件、URL 或粘贴的文本作为输入。基于 https://github.com/kaiokendev/superbig。
ngrok 允许你使用 ngrok 反向隧道服务(免费)远程访问 Web UI。这是内置 Gradio --share 功能的替代方案。
perplexity_colors 根据模型 logits 得出的相关概率为输出文本中的每个标记着色。

如何编写扩展

扩展框架基于你可以在 script.py 中定义的特殊函数和变量。这些函数如下:

函数 描述
def setup() 在导入扩展时执行。
def ui() 在启动 UI 时创建自定义 gradio 元素。
def custom_css() 返回自定义 CSS 字符串。每次加载 Web UI 时应用。
def custom_js() 与上面相同,但用于 JavaScript。
def input_modifier(string, state, is_chat=False) 在输入进入模型之前修改输入字符串。在聊天模式下,应用于用户消息。否则,应用于整个提示词。
def output_modifier(string, state, is_chat=False) 在 UI 中呈现输出字符串之前修改它。在聊天模式下,应用于机器人的回复。否则,应用于整个输出。
def chat_input_modifier(text, visible_text, state) 在聊天模式下修改可见和内部输入。可用于使用自定义内容劫持聊天输入。
def bot_prefix_modifier(string, state) 在聊天模式下应用于机器人回复的前缀。
def state_modifier(state) 在文本生成函数使用之前修改包含 UI 输入参数的字典。
def history_modifier(history) 在聊天模式下开始文本生成之前修改聊天历史。
def custom_generate_reply(...) 覆盖主要的文本生成函数。
def custom_generate_chat_prompt(...) 覆盖聊天模式下的提示词生成器。
def tokenizer_modifier(state, prompt, input_ids, input_embeds) 修改输入到模型的 input_ids/input_embeds。应返回 promptinput_idsinput_embeds。参见 multimodal 扩展以获取示例。
def custom_tokenized_length(prompt) tokenizer_modifier 一起使用,返回 prompt 的标记长度。参见 multimodal 扩展以获取示例。

此外,你可以定义一个特殊的 params 字典。其中,display_name 键用于定义扩展在 UI 中显示的名称,is_tab 键用于定义扩展是否应出现在新标签页中。默认情况下,扩展出现在"文本生成"标签页的底部。

示例:

params = {
    "display_name": "谷歌翻译",
    "is_tab": True,
}

params 字典还可以包含你希望通过 settings.yaml 文件自定义的变量。例如,假设扩展位于 extensions/google_translate,以下代码中的 language string 变量:

params = {
    "display_name": "谷歌翻译",
    "is_tab": True,
    "language string": "jp"
}

可以通过在 settings.yaml 中添加一个名为 google_translate-language string 的键来自定义:

google_translate-language string: 'fr'

也就是说,键的语法是 扩展名-变量名

同时使用多个扩展

你可以通过在 --extensions 后提供多个扩展名(用空格分隔)来同时激活多个扩展。输入、输出和机器人前缀修改器将按指定顺序应用。

示例:

python server.py --extensions enthusiasm translate # 先应用 enthusiasm,然后应用 translate
python server.py --extensions translate enthusiasm # 先应用 translate,然后应用 enthusiasm

请注意,对于:

  • custom_generate_chat_prompt
  • custom_generate_reply
  • custom_tokenized_length

只会使用遇到的第一个声明,其余的将被忽略。

完整示例

以下源代码可以在 extensions/example/script.py 中找到。

"""
一个扩展示例。它本身不做任何事情,但你可以在 return 语句之前
添加转换来自定义 webui 的行为。

从 history_modifier 开始到 output_modifier 结束,这些函数
的声明顺序与它们在生成时被调用的顺序相同。
"""

import gradio as gr
import torch
from transformers import LogitsProcessor

from modules import chat, shared
from modules.text_generation import (
    decode,
    encode,
    generate_reply,
)

params = {
    "display_name": "示例扩展",
    "is_tab": False,
}

class MyLogits(LogitsProcessor):
    """
    在下一个词符被采样之前操作其概率。
    在下面的 logits_processor_modifier 函数中使用。
    """
    def __init__(self):
        pass

    def __call__(self, input_ids, scores):
        # probs = torch.softmax(scores, dim=-1, dtype=torch.float)
        # probs[0] /= probs[0].sum()
        # scores = torch.log(probs / (1 - probs))
        return scores

def history_modifier(history):
    """
    修改聊天历史。
    仅在聊天模式下使用。
    """
    return history

def state_modifier(state):
    """
    修改 state 变量,这是一个包含 UI 中输入值(如滑块和复选框)的字典。
    """
    return state

def chat_input_modifier(text, visible_text, state):
    """
    在聊天模式下修改用户输入字符串(visible_text)。
    你还可以修改用户输入的内部表示(text)以改变它在提示中的显示方式。
    """
    return text, visible_text

def input_modifier(string, state, is_chat=False):
    """
    在默认/笔记本模式下,修改整个提示。

    在聊天模式下,它与 chat_input_modifier 相同,但仅应用于 "text"
    (这里称为 "string"),而不应用于 "visible_text"。
    """
    return string

def bot_prefix_modifier(string, state):
    """
    在聊天模式下修改下一个机器人回复的前缀。
    默认情况下,前缀将类似于 "机器人名称:"。
    """
    return string

def tokenizer_modifier(state, prompt, input_ids, input_embeds):
    """
    修改输入 id 和嵌入。
    由多模态扩展用于在提示中放置图像嵌入。
    仅由使用 transformers 库进行采样的加载器使用。
    """
    return prompt, input_ids, input_embeds

def logits_processor_modifier(processor_list, input_ids):
    """
    向列表中添加 logits 处理器,允许你访问和修改下一个词符的概率。
    仅由使用 transformers 库进行采样的加载器使用。
    """
    processor_list.append(MyLogits())
    return processor_list

def output_modifier(string, state, is_chat=False):
    """
    在呈现 LLM 输出之前修改它。

    在聊天模式下,修改后的版本进入 history['visible'],
    原始版本进入 history['internal']。
    """
    return string

def custom_generate_chat_prompt(user_input, state, **kwargs):
    """
    替换从聊天历史生成提示的函数。
    仅在聊天模式下使用。
    """
    result = chat.generate_chat_prompt(user_input, state, **kwargs)
    return result

def custom_css():
    """
    返回一个 CSS 字符串,该字符串会被附加到 webui 的 CSS 中。
    """
    return ''

def custom_js():
    """
    返回一个 JavaScript 字符串,该字符串会被附加到 webui 的 JavaScript 中。
    """
    return ''

def setup():
    """
    仅在导入扩展时执行一次。
    """
    pass

def ui():
    """
    在绘制 UI 时执行。应在此处定义自定义 gradio 元素及其相应的事件处理程序。

    要了解 gradio 组件,请查看文档:
    https://gradio.app/docs/
    """
    pass