forked from supersonicbi/supersonicbi.github.io
-
Notifications
You must be signed in to change notification settings - Fork 0
/
en.search-data.min.320ac39a9b0f6856121dcc543c13eda5f4fcdb377a2057aa7a961a288554e46a.json
1 lines (1 loc) · 21.8 KB
/
en.search-data.min.320ac39a9b0f6856121dcc543c13eda5f4fcdb377a2057aa7a961a288554e46a.json
1
[{"id":0,"href":"/docs/%E8%AE%BE%E8%AE%A1%E6%80%9D%E8%B7%AF/","title":"设计思路","section":"Docs","content":"通过自然语言界面(Natural Language Interface)访问数据是数据库上古大神们就开始畅想的情境,在学术界也一直是专门的研究方向。对我们影响比较大的两篇论文是IBM在2016年发表的ATHENA和谷歌在2017年发表的Analyza,但它是纯基于规则的工程实现。2017年之后,随着大规模数据集Seq2SQL和Spider发布,基于AI模型的解决方案如雨后春笋般涌现,从seq2seq到slot filling,从schema linking到intermediate representation,各种奇淫技巧不一而足。直到ChatGPT横空出世,基于prompting来实现Text-to-SQL几乎成了大家的共识。\n在项目初期,我们也曾尝试通过prompt engineering让ChatGPT直接生成SQL,但经过多轮迭代,在稳定性和可靠性方面始终无法达到生产可用的期望,总的来说有如下问题:\n语义复杂\n如果涉及多表关联、运算公式、时间转换等复杂语义情况,SQL生成难度变高,LLM输出可靠性会显著降低。 涉及指标计算的场景,如果依赖用户问询来描述,无法保证口径的一致性与确定性。 输出幻觉\n为了让LLM理解schema,需要将所有字段的名称和描述作为context输入,如果schema字段数量多,可能会超过context window限制。因此,基数过大的字段取值一般不会全部放入context,使得LLM无法识别到专有领域的术语。即便将schema全部输入且告知LLM不要随意猜测,仍然有一定几率会预测出错误的字段,甚至可能幻觉出不存在的字段。 相同的语义,不同的语言表达,可能会导致大相径庭的输出结果,无法保证一致性。 推理效率\n当前LLM推理速度还处在10秒+量级,再加上底层数据查询的耗时,同时还无法像纯文本那样的流式输出,非常考验用户的耐心。 当前LLM主流是按token计费,如果所有查询都需要走LLM,MaaS成本会随着查询量线性增长。 我们逐渐意识到,LLM只是看作是意图识别和文本生成的引擎,它还需要其他的组件来配套,才构成一个完整的系统解决方案。可与此类比的是传统OLAP引擎,需要有transformation层的清洗、关联、聚合等建模步骤来配套,才能形成高效稳定的数据服务。\n因此,在SuperSonic项目中我们围绕LLM引入与之配套的工程化组件,来增强语义解析和SQL生成的可靠性。架构图里黄色背景块就是引入的配套组件,下面的篇幅将展开介绍设计思考。\nSemantic Layer\r#\r当AI领域的LLM满级输出吸走大部份聚光灯的时候,BI领域也有一位召唤师在猥琐发育——它就是Semantic Layer(也有称为是Headless BI或者Metric Store)。所以它的核心价值是什么?我们可以用两个拟人化的角色来类比:\n翻译官:将技术名词(表/字段)翻译成业务术语(维度/指标/标签),便于业务用户理解。 大管家:将技术口径(关联关系/运算公式)统一化、精细化地管理起来,便于查帐比对,消除口径混乱。 两类角色的存在都可以提升数据服务质量,增强业务对数据的理解和信任。而随着企业内数据规模和使用场景的不断扩展,对于数据的组织能力和传播能力越来越成为数据驱动落地的关键因素(这似乎跟企业本身的发展是一个道理),所以semantic layer得到越来越多的关注与认可。\n接下来的问题,semantic layer和LLM又有什么联系?我们还是从它的两类角色上来分析:\n翻译官将技术名词翻译成更有意义的业务术语,便于业务用户理解的同时,同样能增强LLM对数据的语义理解。 大管家将技术口径封装起来,LLM不需要考虑关联关系和运算公式,生成复杂度极大地被简化。 因此,既然semantic layer可以帮助人更好地把数据用起来,为什么不顺便帮一下LLM,举手之劳而已。\nSchema Mapper\r#\r前文有提到LLM的token限制问题,主要是因为想要暴力求解,将全部字段的名称和取值一股脑都丢给LLM。直观分析,可以在前置环节增加映射机制,只保留能在输入文本中映射上的字段,可以极大地减少token使用,即便不超过限制,也能节省推理成本。这就是Schema Mapper组件的由来。\n当前的设计方案是,定期从semantic model中抽取名称、别名、取值来构建词典,形成内部的knowledge base。查询解析阶段,先对输入文本分词,再采用n-gram词典探测的机制。经过前期调研,中文NLP框架HanLP相对成熟,可以满足需要。\nSchema mapper会将所有达到匹配阈值要求的schema项及其相似度得分一并保存到info对象,传递给后续semantic parsing环节引用,最终会由parser挑选输入给LLM。\n与此同时,schema mapper可以定制扩展,并通过Java SPI配置的方式替换或补充SuperSonic的默认实现。\nSemantic Corrector\r#\r针对前文提到的推测错误和幻觉问题,一个方向是对prompt不断试验打磨,但现阶段仍然是玄学成分居多。另一个方向是,在LLM输出的后置环节增加修正机制,将明显错误的表达予以修复。这就是Semantic Corrector组件的由来。\n当前的设计方案是,从LLM生成的SQL中解析出表、字段、取值等名词,逐个检查合法性,将不合法名词通过类似schema mapping的方式去knowledge base尝试找到正确的匹配。比如,LLM可能将取值映射到了错误的字段,通过corrector尝试找到正确的字段映射,并改写SQL。\n与此同时,semantic corrector可以定制扩展,并通过Java SPI配置的方式替换或补充SuperSonic的默认实现。\nRule-based Parser\r#\r针对前文提到的效率问题,除了做时间的朋友,等待LLM进化突破之外,还可以想办法在应用层规避。比如,对于一些简单的问题输入,可以尝试基于规则来做语义解析,这也是从Google Analyza论文里带来的启发。这就是Rule-based Parser的由来。\n当前的设计方案是,通过经验整理一份表单,如下表所示,明确列举每类语义对象(指标/维度/取值/时间/算子)的组合会映射到哪一种查询意图。Rule-based parser再根据schema mapping的结果,从表单中查到对应的查询意图,这个有点类似slot filling的思路。\n引入Semantic Parser的抽象,分别有rule-based和LLM-based的实现。输入问题首先经过rule-based parser,如果有查询意图命中,则根据启发性算法来决定是否可以跳过LLM-based parser。当前,启发性算法会根据schema mapping命中的词汇总长度除以问题总长度来判断,超过配置的阈值则认为规则可以满足需要,决定跳过LLM,如果跳过那么提升效率的目的就达到了。\n与此同时,semantic parser可以定制扩展,并通过Java SPI配置的方式替换或补充SuperSonic的默认实现,也可以选择完全去掉rule-based parser配置。\nChat Plugin\r#\rSuperSonic的主链路主要涉及两个步骤:1、LLM解析语义,生成逻辑SQL,提交semantic layer;2、semantic layer生成物理SQL,提交底层OLAP引擎执行。但是,既然已经有了统一的ChatBI界面,是否能兼容其他的场景,比如文档知识库、数据看板,它们的执行过程不同于SuperSonic主链路。这就是Chat Plugin组件的由来。\n当前的设计方案是,三方插件可以通过WebPage(将直接IFrame嵌入展现)或者WebService(HTTP调用获取返回)两种方式来注册,后续会当作是一种工具来使用。当用户输入问题时,如何选择出合适的插件工具?经典的方式有以下两种:\n向量召回:插件在注册时可以设定一些示例问题,提前通过LLM向量化存储到向量数据库。解析输入问题时,将输入文本同样经过LLM向量化后,从向量数据库根据相似度来召回,通过最匹配的示例问题找到相对应的插件; 函数调用:插件在注册时可以配置函数名称和描述,利用LLM的function call能力来直接根据输入问题选择函数,并找到对应的插件。 两种方式可以结合使用,优先走向量召回流程,如果相似度没有达到配置的阈值,则继续用函数调用来选择。\n"},{"id":1,"href":"/docs/%E7%B3%BB%E7%BB%9F%E6%9E%84%E5%BB%BA%E5%92%8C%E5%90%AF%E5%8A%A8/%E7%8E%AF%E5%A2%83%E4%BE%9D%E8%B5%96/","title":"环境依赖","section":"系统构建和启动","content":"Python 服务 (如果需要用到LLM的能力, 需要启动python服务)\nPython版本: 3.9+ pip版本: 3.9+\n其它需要用到的包(启动服务的时候, 会默认检测安装):\nlangchain==0.0.207 openai==0.27.4 fastapi==0.95.1\nchromadb==0.3.21 tiktoken==0.3.3 uvicorn[standard]==0.21.1(windows: uvicorn==0.21.1)\npandas==1.5.3\n注意事项:\n前往supersonic/chat/core/src/main/python/llm/run_config.py配置LLM key 服务host、port指定: 在supersonic/chat/core/src/main/python/llm/run_config.py中修改 python、pip环境指定: pip路径:在supersonic-common.sh中修改\npython路径:在supersonic-common.sh中修改 注意:0.7.4release版本:在supersonic/chat/core/src/main/python/bin/env.sh中修改\n默认pip路径为/usr/local/bin/pip3,python路径为/usr/local/bin/python3, 若不在这个路径,需要在修改成自己的路径\nWindows下需要将python和pip指令配置好环境变量\n后端服务\nJDK版本: 1.8+\n前端服务\nNode版本: 16+ pnpm\n"},{"id":2,"href":"/docs/%E7%B3%BB%E7%BB%9F%E6%9E%84%E5%BB%BA%E5%92%8C%E5%90%AF%E5%8A%A8/%E6%9E%84%E5%BB%BA%E5%92%8C%E5%90%AF%E5%8A%A8/","title":"构建和启动","section":"系统构建和启动","content":"Release包启动\n下载最新release包 sh bin/supersonic-daemon.sh start http://localhost:9080 IDE启动(后端直接访问前端资源的方式) sh assembly/bin/supersonic-build.sh 执行构建 IDE本地启动Java类StandaloneLauncher http://localhost:9080 IDE启动(前后端分开启动的方式) IDE本地启动Java类StandaloneLauncher 进入webapp目录,执行sh start-fe-dev.sh直接启动前端服务 http://localhost:9000 注意这里是9000端口 Source Code启动 sh assembly/bin/supersonic-build.sh 执行构建 sh assembly/bin/supersonic-daemon.sh start http://localhost:9080 PS:\nWindows环境均有提供对应的bat脚本, 执行即可\n系统目前支持两种访问LLM和向量库的方式:\na. Java服务通过langchain4j直接访问LLM的方式, 只需要按如上方式启动服务即可\nb. 另起Python服务的方式来访问LLM, 执行sh assembly/bin/supersonic-daemon.sh start pyllm即可, 这条命令会同时启动Python服务和Java服务, 只不过是通过Python服务 来访问LLM\nJava和Python两种访问LLM的相关配置均可参考LLM与text2sql配置\n执行构建和启动之前, 请先查看环境依赖\nUbuntu环境, 启动方式同上, 若出现报错, 可尝试https://support.huaweicloud.com/intl/zh-cn/deployman_faq/deployman_faq_1016.html\n启动之后, 可以到logs目录下查看日志, llm解析服务相关日志可以到llm/logs目录下查看\n数据库表结构可直接参考launcher/standalone下的sql脚本, h2数据库schema-h2.sql, data-h2.sql, mysql数据库schema-mysql.sql, data-mysql.sql, 这两个脚本均为最新表结构, 每次发版更新的sql会放到sql-update.sql (第一次启动不需要管sql-update.sql, 只是已经在mysql上跑过, 如果不想重新建表导数据, 就需要对照sql-update.sql中的sql执行日期来进行表结构更新)\n系统默认对h2数据库支持样例数据, 若需要基于本地mysql查看样例数据, 可执行schema-mysql.sql来创建最新表结构, 并执行data-mysql.sql把样例数据写入mysql, 之后系统在启动的时候会自动把系统元数据和会话数据写入mysql表,系统启动成功后可在页面看到样例数据, 详细可参考DemoLoader。若需要从h2切换至mysql, 按如下正常配置即可\nspring:\rdatasource:\rurl: jdbc:mysql://localhost:3306/your_database?useUnicode=true\u0026amp;characterEncoding=UTF-8\u0026amp;useSSL=false\rusername: your_username\rpassword: your_password\rdriver-class-name: com.mysql.jdbc.Driver\rdemo:\renabled:\rtrue "},{"id":3,"href":"/docs/%E7%B3%BB%E7%BB%9F%E6%9E%84%E5%BB%BA%E5%92%8C%E5%90%AF%E5%8A%A8/llm%E4%B8%8Etext2sql%E9%85%8D%E7%BD%AE/","title":"LLM与text2sql配置","section":"系统构建和启动","content":"语言模型的使用是SuperSonic的重要一环。能显著增强对用户的问题的理解能力,是通过对话形式与用户交互的基石之一。在本项目中对语言模型能力的应用主要在 LLM 和 Embedding 两方面, 且支持Java和Python两种访问语言模型的方式, 下面分别介绍这两种访问方式的配置。\nJavaLLMProxy\r#\r服务默认启动方式就为Java访问语言模型的方式, 语言模型相关配置可直接通过YAML文件来配置, 目前在配置中支持配置访问open-ai的key和LLM模型的名称 PythonLLMProxy\r#\rPython访问LLM的方式需要通过sh assembly/bin/supersonic-daemon.sh start pyllm来启动Python服务, 该命令同时也会启动Java服务, 但通过Python服务来访问LLM。 Python服务默认使用的模型中,LLM选用闭源模型 gpt-3.5-turbo-16k,Embedding模型选用开源模型 GanymedeNil/text2vec-large-chinese。用户可以根据自己实际需求进行配置更改。\n配置方式 LLM模型的配置\r#\rLLM模型相关的配置,在 supersonic/chat/core/src/main/python/config/run_config.ini 进行配置。 LLM默认采用OpenAI的闭源模型 gpt-3.5-turbo-16k,用户可以根据自己的实际需要选择LLM模型的提供方,例如Azure、文心一言等。通过[LLMProvider]下的LLM_PROVIDER_NAME 变量进行配置。需要注意的是,现阶段支持配置的模型提供方必须能够被langchain所支持,提供方的名字可以在langchain文档中查询。 LLM的相关变量在[LLMModel]下进行配置,例如openAI的模型,需要提供 MODEL_NAME、OPENAI_API_KEY、TEMPERATURE 等参数配置。不同的LLM提供方需要的配置各不相同,用户可以根据实际情况配置相关变量。 Embedding模型配置\r#\rEmbedding模型默认采用开源模型 GanymedeNil/text2vec-large-chinese。用户可以根据实际需要配置适合的Embedding模型;通过[Text2Vec]下 HF_TEXT2VEC_MODEL_NAME 变量进行配置,为了使用方便采用托管在HuggingFace的源,初次启动时自动下载模型文件。 LLM与embedding配置 FAQ\r#\r可以用开源的LLM模型替代OpenAI的GPT模型吗? 暂时不能。我们测试过大部分主流的开源LLM,在实际使用中,在本项目需要LLM提供的逻辑推理和代码生成场景上,开源模型还不能满足需求。 我们会持续跟进开源LLM的最新进展,在有满足要求的开源LLM后,在项目中集成私有化部署开源LLM的能力。 可以用国产的闭源模型替代OpenAI的GPT模型吗? 据部分用户反馈,在他们的场景下文心一言、混元等国产闭源模型的效果与GPT3.5差距不大;整体而言GPT3.5及GPT4适用的场景会更广泛一些。用户可以在自己的场景下修改LLM的相应配置,试一试实际效果。 GPT4、GPT3.5、GPT3.5-16k 这几个模型用哪个比较好? GPT3.5、GPT3.5-16k 均能基本满足要求,但会有输出结果不稳定的情况;GPT3.5的token长度限制为4k,在现有CoT策略下,容易出现超过长度限制的情况。 GPT4的输出更稳定,但费用成本远超GPT3.5,可以根据实际使用场景进行选择。 Embedding模型用其他的可以吗? 可以。可以以该项目text2vec的榜单作为参考,然后在HuggingFace找到对应模型的model card,修改HF_TEXT2VEC_MODEL_NAME变量的取值。 启动时,首次下载Embedding模型需要会链接HuggingFace的源进行下载,如果网络不通怎么办? 可以到HuggingFace的官网找到对应的model card,然后将模型下载到本地。在supersonic/chat/core/src/main/python/config/run_config.ini 中将HF_TEXT2VEC_MODEL_NAME变量配置为模型所在的绝对路径。 LLM在text2sql中的应用\r#\rtext2sql的功能实现,高度依赖对LLM的应用。通过LLM生成SQL的过程中,利用小样本(few-shots-examples)通过思维链(chain-of-thoughts)的方式对LLM in-context-learning的能力进行引导,对于生成较为稳定且符合下游语法解析规则的SQL非常重要。用户可以根据自身需要,对样本池及样本的数量进行配置,使其更加符合自身业务特点。\ntext2sql运行中更新配置的脚本\r#\r如果在启动项目后,用户需要对text2sql功能的相关配置进行调试,可以在修改相关配置文件后,通过以下2种方式让配置在项目运行中让配置生效。 执行 supersonic-daemon.sh reload llmparser 执行 python examples_reload_run.py "},{"id":4,"href":"/docs/%E4%BA%A7%E5%93%81%E4%BD%BF%E7%94%A8%E6%89%8B%E5%86%8C/%E6%9E%84%E5%BB%BA%E8%AF%AD%E4%B9%89%E6%A8%A1%E5%9E%8B/","title":"构建语义模型","section":"产品使用手册","content":"构建语义模型是使用超音数的第一步。在这个模块中, 它可以连接上你的数据库引擎, 并通过简单方便的方式来帮助你将物理数据建模为维度和指标等逻辑概念。建模完成后, 你就可以在问答中通过自然语言的方式来和你的物理数据交互啦~\n问题示例\n为了帮助你更好地理解建模的过程, 我们通过一个问题示例来进行介绍: 超音数本身作为一个产品, 那么如何用语义建模来统计它的埋点访问数据呢?比如超音数在一段时间内的访问用户数是多少?这些用户的访问次数和停留时长是怎样的?这些用户来自哪些部门?这些用户看了哪些页面?分别看了多少次?等我们建模完成, 这些问题的答案也就浮出水面了。\n在超音数中, 模型归属于主题域, 主题域类似于一个分类的概念, 用户可以按自己的业务场景去创建主题域, 然后在主题域下面创建模型。\n1. 创建一个主题域\r#\r如图1-1所示, 为了统计超音数的埋点访问情况, 我们创建了一个叫\u0026quot;超音数\u0026quot;的主题域作为示例:\n2. 创建一个数据库连接\r#\r为了进行数据查询, 我们首先需要创建一个数据库连接, 创建一个数据库连接主要分为三个步骤,\n填写连接信息 点击测试连接, 若连接测试通过, 则可点击保存。否则, 返回步骤1 点击保存。 如图1-1所示, 由于超音数的埋点访问数据被存放在H2数据库中, 因此我们创建了一个H2数据库实例作为例子。除了H2数据库以外, 我们还支持MySQL, ClickHouse等多种常见数据库。\n需要说明的是, 在这里创建数据库之后, 并不是所有人都可以查询这个数据库链接的数据, 需要在图2-1表单上进行授权。\n管理员: 可以编辑这个数据库链接的人\n使用者: 可以使用这个数据库链接查询数据的人\n3. 创建数据模型\r#\r有了数据库连接之后, 我们就可以把物理数据抽象为一个个数据模型。在超音数中, 数据模型是对数据库中数据的一种逻辑层面上的抽象, 它既可以直接指代一张物理表, 也可以由一段SQL逻辑表示而成。数据模型中涉及的字段可被指定为维度或者度量, 而这些维度和度量又可以衍生出更复杂的维度和指标。如图3-1, 超音数提供了两种创建数据模型的方式。\n其中, 快速创建 可以直接指定一张物理表来把它创建为数据模型, 而SQL脚本 则提供了更为灵活的数据模型创建方式, 我们可以通过写一条逻辑SQL来把它指定为数据模型\n如图3-2为通过SQL脚本的方式创建数据模型, 首先需要我们填写一些基本信息, 如数据模型名称和描述。\n然后我们写一条SQL来表达我们的数据模型逻辑, 然后点击运行, 就可以看到这条SQL查询出来的数据, 校验数据无误之后, 我们可以点击生成数据模型, 需要注意的是, 这里创建数据模型选择数据库链接的时候, 需要有数据库的使用者权限.\n如图3-4所示, 执行完SQL之后, 根据SQL执行结果, 需要填写一些字段信息, 把数据模型的字段指定为维度或者度量, 其中日期和主键为特殊的维度。\n维度主要用于筛选和分组\n度量主要标识数值类型字段, 用来进行聚合计算\n日期字段主要用于标识, 方便问答进行数据查询。\n主键则用于不同数据模型之间的连接字段, 有了连接字段后,就可以在画布进行连接关系的配置, 配置完成, 在查询模型数据的时候, 多个模型之间就可以进行Join连接了\n把字段指定为维度/度量之后, 还可选择是否勾选快速创建单选框。若勾选, 则会直接把选中的维度/度量批量创建到维度/指标列表。 若不勾选, 但字段已被选定为维度/度量, 该字段虽然不会直接被创建到维度/指标列表, 但是后续在创建衍生维度/指标的时候也可作为表达式中的字段被用上。 如图3-5所示, 为我们创建的3个数据模型示例, 分别为超音数用户停留时长统计, 访问次数和访问人数统计, 用户部门统计。\n4. 创建维度\r#\r如图4-1, 为刚刚创建数据模型时, 通过勾选快速创建按钮创建出来的维度。分别为用户名, 用户所在的部门, 用户浏览过的超音数页面。\n若我们需要更复杂的维度, 如我们需要根据页面来划分模块, 那我们可以点击创建按钮来创建一个更复杂的维度。如图4-2所示\n5. 创建指标\r#\r和维度类似, 如图5-1为通过快速创建按钮创建出来的指标, 分别为访问超音数的次数, 人数和停留时长。这几个指标都可以在用户、部门 、页面等分组粒度上进行计算。\n到此为止, 我们就成功把超音数的访问统计数据建模成了相关的数据模型、维度和指标。通过在问答中直接对这些维度和指标进行提问, 就可以回答我们在介绍开头提到的那些问题啦!\n"}]