Skip to content

ylsdamxssjxxdd/eva

Repository files navigation

机体

直观的大模型应用软件:机体 (qt5+llama.cpp)

[ 中文 | English ]

特点

  • 直观 👁️

    • 清晰的展示大模型预测下一个词的过程

    • 输出区的内容就是模型的全部现实

  • 兼容性 🚀

    • 支持windows和linux
  • 多功能 🦾

    本地模型对话、网络模型对话、模型api、网页服务、智能体、多模态、知识库问答、代码解释器、软件控制、文生图、声转文、模型量化、模型评测

快速开始

  1. 下载一个机体

        windows下载 .exe 后缀的程序,linux下载 .AppImage 后缀的程序
        其中cpu版本使用avx加速,兼容性较好;cuda版本使用nvidia显卡加速;vulkan版本可以使用任意显卡加速,速度不如cuda版本
  2. 下载一个gguf格式模型

  3. 装载!

    • 点击装载按钮,选择一个gguf模型载入内存
  4. 发送!

    • 在输入区输入聊天内容,点击发送
  5. 加速!

    • 点击设置,调整gpu负载层数,显存充足建议拉满,注意显存占用超过95%的话会很卡

    • 同时运行sd的话要确保给sd留足显存

基础功能

两种模式
  1. 本地模式:用户左键单击装载按钮,通过装载本地的模型进行交互

  2. 链接模式:用户右键单击装载按钮,输入某个模型服务的api端点进行交互(要求服务可以提供default模型且没有设置API-KEY)

三种状态
  1. 对话状态

    • 机体的默认状态,在输入区输入聊天内容,模型进行回复

    • 可以事先约定好角色

    • 可以使用挂载的工具

    • 可以上传csv格式的题库进行测试

    • 可以按f1截图,按f2进行录音,截图和录音会发送给多模态或whisper模型进行相应处理

  2. 补完状态

    • 在输出区键入任意文字,模型对其进行补完
  3. 服务状态

    • 机体成为一个开放api端口的服务,也可以在网页上进行聊天
六个工具

在 本地模式 + 对话状态 下,用户可以点击约定为模型挂载工具

    原理是在系统指令中添加一段额外的指令来指导模型调用相应的工具
    每当模型预测结束后,机体自动检测其是否包含调用工具的json字段,若有则调用相应的工具,工具执行完毕后将结果再发送给模型继续进行预测
  1. 计算器

    • 模型输出计算公式给计算器工具,工具将返回计算结果

    • 例如:计算888*999

    • 调用难度:⭐

  2. 软件控制台

    • 模型输出软件控制序号给软件控制台工具,工具将返回执行结果

    • 例如:播放音乐

    • 调用难度:⭐

  3. 系统终端

    • 模型输出终端指令给系统终端工具,工具将返回指令执行结果

    • 例如:我电脑的ip地址是多少

    • 调用难度:⭐⭐⭐

  4. 代码解释器

    • 模型输出完整的python代码给代码解释器工具,工具将返回执行结果

    • 例如:请用matplotlib绘制一个爱心

    • 调用难度:⭐⭐⭐⭐⭐

  5. 知识库

    • 模型输出查询文本给知识库工具,工具将返回三条最相关的已嵌入知识

    • 要求:用户需要先在增殖窗口上传文档并构建知识库

    • 例如:请问机体有哪些功能?

    • 调用难度:⭐⭐

  6. 文生图

    • 模型输出绘画提示词给文生图工具,工具将返回绘制好的图像

    • 要求:用户需要先在增殖窗口配置文生图的模型路径,支持sd和flux模型

    • 例如:画一个女孩

    • 调用难度:⭐⭐

增强功能

default.mp4
视觉
  • 介绍:在 本地模式 + 对话状态 下可以挂载视觉模型,视觉模型一般名称中带有mmproj,并且只和特定的模型相匹配。挂载成功后用户可以选择图像进行预解码,来作为模型的上文

  • 激活方法:在设置中右击 "挂载视觉" 的输入框选择mmproj模型。可以通过 拖动图片到输入框 或 右击输入框点击<上传图像> 或 按f1进行截图,然后点击发送按钮对图像进行预解码,解码完毕再进行问答

听觉
  • 介绍:借助whisper.cpp项目将用户的声音转为文本

  • 激活方法:右击状态区打开增殖窗口,选择声转文选项卡,选择whisper模型所在路径。回到主界面按f2快捷键即可录音,再按f2结束录音,并自动转为文本填入到输入区

语音
  • 介绍:借助windows系统的语音功能将模型输出的文本转为语音并自动播放

  • 激活方法:右击状态区打开增殖窗口,选择文转声选项卡,选择启用系统声源

辅助功能

模型量化
  • 可以右击状态区弹出增殖窗口,在模型量化选项卡中对未经量化的fp32、fp16、bf16的gguf模型进行量化
debug输出
  • 为了更好的展示模型预测下一个词的过程,本地模式中用户可以拉动状态区向上,点击开启debug输出标签

  • 开启后下一个词的预测由用户手动控制,可以获取更多模型运行的信息

机体同步率测试
  • 在 本地模式 + 对话状态下 可以对模型进行机体同步率测试,右击输入区选择 <机体同步率测试>

  • 主要测试模型的指令遵循能力,同步率越高,模型越强😊

源码编译

展开
  1. 配置环境

  2. 克隆源代码

    git clone https://github.com/ylsdamxssjxxdd/eva.git
  3. 编译

    cd eva
    cmake -B build -DBODY_PACK=OFF -DGGML_VULKAN=OFF -DGGML_CUDA=OFF
    cmake --build build --config Release
    • BODY_PACK:是否需要打包的标志,若开启,windows下将所有组件打包为一个自解压程序,linux下将所有组件打包为一个AppImage文件

    • GGML_CUDA:是否需要启用cuda加速的标志

    • GGML_VULKAN:是否需要启用vulkan加速的标志

行动纲领

展开
  • 装载流程

    • 【ui】->用户点击装载->选择路径->发送释放模型信号->【bot】->释放模型->释放完毕->【ui】->刷新gpu信息->【gpu】->刷新完毕->【ui】->发送设置参数->【bot】->应用设置参数->发送重载信号->【ui】->装载前动作->开始播放动画->发送装载模型信号->【bot】->装载模型->提取模型参数和对话模板->重置上下文->发送装载完成信号->【ui】->加速装载动画->装载动画结束->滚动动画开始->动画结束->强制解锁->触发发送->发送预解码(只解码不采样输出)指令->【bot】->预解码系统指令->发送解码完毕信号->【ui】->正常界面状态->END
  • 发送流程

    • 【ui】->用户点击发送->模式/标签/内容分析->对话模式的话->推理中界面状态->发送输入参数->发送推理信号->【bot】->预处理用户输入->流式循环输出->循环终止->发送推理结束信号->【ui】->正常界面状态->END
  • 约定流程

    • 【ui】->用户点击约定->展示最近一次配置->点击确认->记录用户配置->发送约定参数->【bot】->记录用户配置->发送约定重置信号->【ui】->触发界面重置->发送重置信号->【bot】->初始化模型运行所需组件->发送重置完成信号->【ui】->如果系统指令变化则预解码->END
  • 设置流程

    • 【ui】->用户点击设置->展示最近一次配置->点击确认->记录用户配置->发送设置参数->【bot】->记录用户配置->分析配置变化->END/发送重载信号/发送设置重置信号->【ui】->预装载/触发界面重置->END
  • 预解码图像流程

    • 【ui】->用户上传图像/按f1截图->触发发送->推理中界面状态->发送预解码图像指令->【bot】->预解码图像->占用1024个token->发送解码完毕信号->【ui】->正常界面状态->END
  • 录音转文字流程

    • 【ui】->用户初次按下f2->需要指定whisper模型路径->发送expend界面显示信号->【expend】->弹出声音增殖界面->选择路径->发送whisper模型路径->【ui】->用户再按f2->录音界面状态->开始录音->用户再按f2->结束录音->保存wav文件到本地->重采样wav文件到16khz->发送wav文件路径->【expend】->调用whisper进行解码->解码完毕保存txt结果到本地->发送文字结果->【ui】->正常界面状态->显示到输入区->END
  • 工具调用流程

    • 【ui】->用户点击发送->模式/标签/内容分析->对话模式的情况->推理中界面状态->发送输入参数->发送推理信号->【bot】->预处理用户输入->流式循环输出->循环终止->发送推理结束信号->【ui】->提取模型本次输出中的json字段->发送json字段->发送工具推理信号->【tool】->根据json字段执行相应函数->执行完毕返回结果->【ui】->将返回结果作为发送内容并添加观察前缀->触发发送->···->没有合理的json字段->正常界面状态->END
  • 构建知识库流程

    • 【expend】->用户进入知识库选项卡->用户点击选择模型->选择嵌入模型->启动server->启动完成->自动将server的v1/embeddings端点写入地址栏->用户点击上传选择一个txt文本->文本分段->用户可以按需求修改待嵌入文本段内容->用户点击嵌入文本段->将每个文本段发送到端点地址并接收计算后的词向量->表格中显示已嵌入文本段->发送已嵌入文本段数据->【tool】->END
  • 知识库问答流程

    • 【ui】->工具调用流程->json字段中包含knowledge关键字->发送json字段->发送工具推理信号->【tool】->执行knowledge函数->向嵌入端点发送查询字段->【server】->返回计算后的词向量->【tool】->计算查询字段词向量和每个已嵌入文本段词向量的余弦相似度->返回三个相似度最高的文本段->【ui】->将返回结果作为发送内容并添加观察前缀->触发发送->···->没有合理的json字段->正常界面状态->END
  • 链接流程

    • 【ui】->用户右击装载->配置ip和端点->点击确认->锁定界面->记录配置->连接测试->测试通过->解锁界面->END

    • 链接模式下的其它流程与上面类似,【bot】替换为【net】

  • debug流程

    • 【ui】->用户拉动状态区向上可弹出debug按钮->用户开启debug按钮->点击发送->进入debuging状态->发送流程,只解码采样一次->点击Next->发送流程,只解码采样一次->···->当 检测到停止标志/达到最大输出长度/手动停止 时退出debuging状态->END

概念

展开
  • model(模型): 由一个公式和一组参数组成

  • token(词元): 词的编号,例如,你好 token=123,我 token=14,他的 token=3249,不同模型编号不一样

  • vocab(词表): 该模型训练时所设置的全部词的token,不同模型词表不一样,词表里中文占比越高的往往中文能力强

  • kv cache(上下文缓存): 先前计算的模型注意力机制的键和值,相当于模型的记忆

  • decoding(解码):模型根据上下文缓存和送入的新token计算出向量表,并得到新的上下文缓存

  • sampling(采样):根据向量表计算出概率表并选出下一个词

  • predict(预测):(解码 + 采样)循环

  • predecode(预解码):只解码不采样,用于缓存上下文如系统指令


  • n_ctx_train(最大上下文长度): 该模型训练时能送入解码的最大token数量

  • n_ctx(上下文长度): 用户设置的解码时模型能接受的的最大token数量,不能超过n_ctx_train,相当于记忆容量

  • temperature(温度): 采样时会根据温度值将向量表转为概率表,温度越高随机性越大

  • vecb(向量表): 本次解码中词表里所有token的概率分布

  • prob(概率表): 本次采样中词表里所有token的最终选用概率

待办事项

  • 自行状态(机体自主控制屏幕、鼠标、键盘,完成用户预设的任务)

  • 适配linux(已完成)

  • 英文版本(已完成)

已知BUG

展开
  • 模型推理有内存泄漏,定位在xbot.cpp的采样部分,与qt的qplaintextedit也有关,待修复

  • 链接模式下,无法无间隔的连续发送,通过定时100ms后触发来缓解,定位在xnet.cpp的QNetworkAccessManager不能及时释放,待修复

  • 多模态模型输出异常,需要向llava.cpp对齐,待修复


  • 达到最大上下文长度后截断一次后再达到,解码会失败,通过暂时置入空的记忆来缓解,定位在xbot.cpp的llama_decode返回1(找不到kv槽),没修复(实际上是截断后,送入的token数量与保留的部分依旧超过最大上下文长度,需要再截断一次)

  • 部分字符utf-8解析有问题,已修复(模型输出不完整的utf8字符,需要手动将3个拼接成1个)

  • 切换模型时显存泄露,已修复(使用cuda时,不使用mmp)

  • mingw编译的版本装载时无法识别中文路径,定位在llama.cpp的fp = std::fopen(fname, mode);,已修复(利用QTextCodec::codecForName("GB2312")将字符转码)

  • csv文件存在特殊符号时不能正确解析,定位在utils.cpp的readCsvFile函数,已修复(利用一个改进的解析方法,依赖于一个简单的状态机来跟踪文本段是否位于引号内部,以正确处理字段内的换行符)