LangChain+LLM大模型问答能力搭建与思考

news2024/11/24 4:26:58

1. 背景

最近,大模型(LLMs,Large Language Models)可谓是NLP领域,甚至整个科技领域最火热的技术了。凑巧的是,我本人恰好就是NLP算法工程师,面临着被LLMs浪潮淘汰的窘境,决定在焦虑之余,试着用新家伙,去解决解决老问题(缓解一下焦虑…)

所以是什么老问题呢?——那就是Bert解决了过、但问题依旧存在的那个——垂直领域问答

2. 原思路简介

由于目前的确已经有许多类似的、写得很优秀的大佬写的文章了,所以我本文不会过多涉及具体的代码。我更倾向于探讨一下我们怎么用这项**“新技术”**,来解决之前就有的、而且颇有价值的”老问题“

首先,最基础的架构我们还是要说一下(免得一段时间以后回顾的时候一脸懵逼,只剩吹牛了)

我们先回顾一下,Bert时代的垂直领域问答系统是怎么构建的?
Bert时代的垂直领域问答系统架构示意图

如上图所示,这就是个问答系统的大概面貌了。当然了,还有些其他辅助模块没在这里体现,这里只拿出了最关键的几个部分:

  1. query理解:充分理解query含义,挖掘query信号,给下一轮的doc(文档)”粉碎机“提供弹药!
  2. 文档召回:这里的召回方式大概可分为2大类,分别是基于query理解得到的信号召回,以及向量召回。
    1. 信号召回:基于ES或其他什么类ES自研框架(为什么要自研,还不是为了体现价值orz…)实现,可以简单理解为关键词召回,即从query和doc中分别找到关键词,然后进行匹配、打分;
    2. 向量召回:信号召回显然是基于”字面“的,而向量召回则是基于语义的。将doc提前向量化建库,然后query再向量化后进行向量检索。
    3. 最后,基于以上两路召回的文档得分,再结合一些其他trick(如质量打分)进行综合排序,取topK进入下一轮大逃杀!
  3. 答案抽取:使用预训练好的模型,分别对topK文档里的答案进行抽取。对于上一代Berter(哦不NLPer)而言,主模型都是Bert或其徒子徒孙。现在,则是最时髦的LLM
  4. 答案处理:后处理模块,可将得到的答案再次排序、可做答案融合、也可根据业务需要,进行合理的后处理,最后输出。

3. LLM出现以后的世界

3.1 LLM时代和Bert时代的差异

那么,在现如今ChatGPT、ChatGLM、Moss、LAMMA等大模型满天飞的世界,上述那套系统有什么变化了呢?

其实,这套系统整体流程变化并不大,只不过是将”答案抽取“模块的Bert时代模型替换成了LLMs时代的模型。而由于LLM在模型能力、允许输入长度等方面都比Bert强不少,所以一定程度上,LLMs时代这套系统对其他几个模块的要求也降低了

举个例子,在Bert时代,query理解是个要做得很重、异常重要的模块,毕竟如果这里能力不足,那下游模型就”巧妇难为无米之炊了“,我上面那张图里query理解部分每个子模块都能撑得起一大块工作。而大家都知道,端到端的模型是大家一直追求的(是吗?毕竟这样要我们NLPer还能做啥?),而且能力足够的端到端模型可以最大程度减少信息损失,所以能力更强的LLMs直接把这个模块的工作包揽了下来,原本的query分词、分类、纠错、关键词等工作变成了制定合适的Prompt然后调试,具体的query理解,就由LLM来搞定了。

下面,我再简介一下结合LLM时,垂直领域问答的架构的样子

3.2 LLM时代垂直领域知识库问答常用架构

LLM时代垂直领域知识库问答架构

架构异常简单,暂时能力所限,仅为博君一笑~

如图所示,能看得出,整体架构比Bert时代的简单很多。我们对照着之前的架构来说:

  1. query理解 VS提问模块:前面举过例子,目前提问模块在当前架构下已经几乎没有什么任务了,但如果你想增加一路关键词召回,那么这里也可以借助大模型的能力来解决,用大模型(当然,也可以是传统nlp模型或规则词表)帮你完成关键词提取,然后到下一步中进行使用ES做关键词召回

  2. 两版文档召回模块:这一部分差别其实不大,但随着LLMs的模型能力提升,对于召回质量的忍耐度也在提升。由于Bert时代模型往往有512 tokens的长度限制,所以我们要更加小心地做好召回文段排序和截断、文段之间overlap等事情。但随着大模型目前普遍将文本可输入长度扩到了8K、甚至是16K/32K(当然这里指的是字符,汉字字数会少一些),这就意味着如果需要,我们可将更多的文段喂给LLM。也正因为此,我们现如今往往只用向量召回(LangChain)即可达到要求。当然了,为了进一步提升召回文章的丰富度,开发额外的ES关键词召回、甚至更复杂的召回链路也是可行的。笔者之前有幸在某大厂负责过电商搜索引擎的召回模块,各路召回之复杂实在让人欲仙欲死,然而它们也确实是有用的,有些召回路径满足的是搜索的精准,有的召回路径满足的是物料的丰富,有的召回路径从用户历史兴趣角度考量,也有的召回路径从品类、产地、功能等多角度试图猜到用户所需。不过,由于知识库问答场景往往没有这么多目标,所以我们就尽可能做的轻一些——less is more

  3. 答案抽取模块VS大模型问答模块:虽然核心的模型从Bert变成了本地的微调过的ChatGLM、或ChatGPT-api,但整体思路是一致的。Bert时代首先需要将处理后的query和若干召回的doc拼接成类似[CLS]query[SEP]doc1, [CLS]query[SEP]doc2, …类似的样子,然后分别送给Bert进行答案抽取、输出;LLMs时代,则是将召回的doc和用户query装配成最终Prompt,类似的样子如下:

    """已知信息:
    {context} 
    
    根据上述已知信息,简洁和专业地回答用户问题。如果无法从中得到答案,请说 “根据已知信息无法回答该问题” 或 “没有提供足够的相关信息”,不允许在答案中添加编造成分,答案请使用中文。 问题是:{question}
    """
    

    以上Prompt模板参考链接。最后,LLM会将答案输出。

  4. 答案处理模块在LLM版本架构中,不再需要这一模块,因为LLM已经将输入资料整合并完成回答了。但Bert时代,由于多段资料分别和query拼接进行答案抽取,所以结果还要对多个答案进行排序。

4. LangChain+LLM实战心得体会

具体LangChain+LLM的代码,笔者参考该repo,并在上面进行了些细微的二次开发。由于该项目已经非常完备了,所以不再赘述。我在这里,主要说一下我在项目开发中遇到的问题和一点思考:

4.1 数据处理和清洗方面

  1. 关于目录:目录部分应提前识别并删除

    这部分关键词巨多(误命中)、各种标点符号巨多(误分段)、大多不是自然语言(用来做目录索引的,没实际的文本含义),引入目录,会在文档召回阶段通过向量或关键词产生大量误召回,建议直接咔嚓掉

  2. 文档分段长度:模型允许的情况下,能长则长;可根据数据酌情向后扩展

    在大模型可接受文本总字数有限的情况下,增加召回数量和增加单文档长度的权衡

    • 首先,由于我所处理的数据是相对干货的政策法规和企业规章,所以文章质量较高;其次,相似的内容较少出现在多个出处、而且有些政策文本会有不少1.xxx, 2.xxx, ..., 10.xxx这种不适合切割的超长内容,所以对我的数据而言,与其召回更多个短文本段,还不如召回更少的长文本段,以减少低相关杂质引入,也防止有用内容被截断。

    • 不过之前我也处理过各种政策解读、财经类新闻的语料,这种语料往往良莠不齐且同一件事有多个相似文章在描述,为了确保结果的全面性,则是召回更多个短文本段更好。

    关于分段截断的问题

    • 一般通用分段方式,是在固定max_length的基础上,对出现。/;/?/....../\n等等地方进行切割。

    • 但这种方式显然比较武断,面对特殊情况需要进一步优化。比如前面的那个1.xxx, 2.xxx, ..., 10.xxx超长内容的情况,直接按这种方法切割就会导致潜在的内容遗漏。

    • 对于这种候选语料”内聚性“很强的情况,容易想到,我们要么在切割语料时动手脚(不把连续数字符号所引领的多段文本切开);要么在切割时照常切割、但在召回时动手脚(若命中了带连续数字符号的这种长文本的开头,那么就一并把后面连续数字符号引领的多段文本一起召回)。笔者目前只想到了这两种方法且还没具体做实验,只是凭空想来,前者方案有较明显瑕疵,因为这样会——

      1. 相对于更短文段而言,长文段的语义更丰富,每个单独的语义点更容易被淹没,所以在有明确语义query的召回下这种长文段可能会吃亏;
      2. 长文段一旦被召回,只要不是针对整段文本的提问,那么也是引入了更多的噪声(不过鉴于LLM的能力,这可能也无伤大雅,就是费点显存or接口费用了)

      但后者就显得更灵活些,不过确实也不够聪明。暂时没想到其他办法,有好想法的人可以来交流一下~

    • 此外,有研究表明,长文本作为输入LLM输入时,LLM倾向于更关注长文本的开头、结尾处,然而中间部分的语义可能会被忽略。这里挖个小坑,下次再来关注一下这方面问题

4.2 模型方面

  1. 调整temperature参数规避模型”知识幻觉“

    • 对于知识库问答而言,知识幻觉(一本正经的胡说八道)是最头疼的事情。对于ChatGPT(gpt-3.5-turbo)而言,笔者实验过,当temperature<=0.1,可以有效避免“知识幻觉”(即Prompt中没有问题答案,ChatGPT就会回答”根据已知信息无法回答该问题“),不过这也可能让模型过分谨慎(即使有语义类似的答案,模型也倾向于那不是提问范围内的)。建议可以再尝试一些0.1~0.5之间的temperature,在最大化模型联想能力的同时,确保回复的可靠性

    • 但对于ChatGLM-6B(v1),该模型temperature取值范围在[0, 1],笔者尝试过0.1、0.01等数值,仍然会出现较为严重的模型幻觉。不知道ChatGLM2-6B效果会不会好些。不过6B的打不过号称175B的ChatGPT,也是正常

4.3 问题解决思路方面

这部分只是个人在问题解决过程中的一点想法,与大家分享。

  1. 明确多文档下的知识点问答,和单文档总结之间的区别

    • 该项目LangChain+LLM的思路,是针对多文档下的知识点问答的,目标是在海量语料中精准找到几小段参考文档然后总结出答案;
    • 而单文档总结,即类似ChatPDF的需求,和本项目目标不一致。ChatPDF的目标是尽可能全面地总结出整篇文档的信息。这个需求以目前ChatGPT可接受的16K上下文而言,不少文档可以直接丢进去问答,无需使用召回工具先做知识检索,不完全属于该项目解决的问题范围。
  2. 对于效果不佳的情况,首先应该从更高的角度思考,到底是当前技术不达标,还是使用场景不契合。用检索+问答这种范式解决其不擅长的问题、然后再此基础上搞一大批trick,是非常不可取的,应尽量避免

    • 举个例子,有人问这种问答模式能否解决Excel表格问答?这当然可以试试,结果对表格进行问答效果很差——这个结果很容易预期,毕竟CoT的思想就提到过,做推理、算数学题,这种需要一步步思考的任务在加以一步步引导的情况下,LLM才能得到不错的结果。那么,我们应该在检索+LLM这个项目上做优化以解决Excel表格的问答问题吗?非也。我们应该意识到Excel、或者其他文件中的表结构本身属性是表格,表格是结构化数据、文本是非结构化的,而检索系统(文本召回系统)本身就是为非结构化数据准备的。所以要解决excel文件问答的问题,或许可以把它归类到“NL2SQL”上,用代码/SQL的方式去解决。

    • 我做了简单的尝试,供大家参考,后台模型gpt-3.5-turbo-16K:

      来自你的消息:

      排名球员球队得分命中-出手命中率命中-三分三分命中率命中-罚球罚球命中率场次上场时间
      1乔尔-恩比德76人33.1011.00-20.1054.8%1.00-3.0033%10.00-11.7085.7%6634.60
      2卢卡-东契奇独行侠32.4010.90-22.0049.6%2.80-8.2034.2%7.80-10.5074.2%6636.20
      3达米安-利拉德开拓者32.209.60-20.7046.3%4.20-11.3037.1%8.80-9.6091.4%5836.30
      4谢伊-吉尔杰斯-亚历山大雷霆31.4010.30-20.3051%0.90-2.5034.5%9.80-10.9090.5%6835.50
      5扬尼斯-阿德托昆博雄鹿31.1011.20-20.3055.3%0.80-2.7027.5%7.90-12.2064.5%6332.10
      6杰森-塔特姆凯尔特人30.109.80-21.1046.6%3.20-9.3035%7.20-8.4085.4%7436.90
      7多诺万-米切尔骑士28.3010.00-20.6048.4%3.60-9.3038.6%4.70-5.4086.7%6835.80
      8杰伦-布朗凯尔特人26.6010.10-20.6049.1%2.40-7.3033.5%3.90-5.1076.5%6735.90
      9贾-莫兰特灰熊26.209.30-19.9046.6%1.50-4.9030.7%6.10-8.1074.8%6131.90

      以上这些人谁的出战场次最多?所有人平均出战多少场次?直接给出答案


      来自 ChatGPT 的消息:

      以上这些人中,贾-莫兰特的出战场次最多,共计61场。

      所有人的平均出战场次为63.1场。


      来自你的消息:

      排名球员球队得分命中-出手命中率命中-三分三分命中率命中-罚球罚球命中率场次上场时间
      1乔尔-恩比德76人33.1011.00-20.1054.8%1.00-3.0033%10.00-11.7085.7%6634.60
      2卢卡-东契奇独行侠32.4010.90-22.0049.6%2.80-8.2034.2%7.80-10.5074.2%6636.20
      3达米安-利拉德开拓者32.209.60-20.7046.3%4.20-11.3037.1%8.80-9.6091.4%5836.30
      4谢伊-吉尔杰斯-亚历山大雷霆31.4010.30-20.3051%0.90-2.5034.5%9.80-10.9090.5%6835.50
      5扬尼斯-阿德托昆博雄鹿31.1011.20-20.3055.3%0.80-2.7027.5%7.90-12.2064.5%6332.10
      6杰森-塔特姆凯尔特人30.109.80-21.1046.6%3.20-9.3035%7.20-8.4085.4%7436.90
      7多诺万-米切尔骑士28.3010.00-20.6048.4%3.60-9.3038.6%4.70-5.4086.7%6835.80
      8杰伦-布朗凯尔特人26.6010.10-20.6049.1%2.40-7.3033.5%3.90-5.1076.5%6735.90
      9贾-莫兰特灰熊26.209.30-19.9046.6%1.50-4.9030.7%6.10-8.1074.8%6131.90

      以上这些人谁的出战场次最多?所有人平均出战多少场次?使用pandas计算,给出可执行代码,无需将全部数据重新列举一遍


      来自 ChatGPT 的消息:

      您可以使用以下代码来计算出战场次最多和平均出战场次:

      import pandas as pd
      
      # 创建数据表
      data = {
          '排名': [1, 2, 3, 4, 5, 6, 7, 8, 9],
          '球员': ['乔尔-恩比德', '卢卡-东契奇', '达米安-利拉德', '谢伊-吉尔杰斯-亚历山大', '扬尼斯-阿德托昆博', '杰森-塔特姆', '多诺万-米切尔', '杰伦-布朗', '贾-莫兰特'],
          '球队': ['76人', '独行侠', '开拓者', '雷霆', '雄鹿', '凯尔特人', '骑士', '凯尔特人', '灰熊'],
          '得分': [33.10, 32.40, 32.20, 31.40, 31.10, 30.10, 28.30, 26.60, 26.20],
          '命中-出手': ['11.00-20.10', '10.90-22.00', '9.60-20.70', '10.30-20.30', '11.20-20.30', '9.80-21.10', '10.00-20.60', '10.10-20.60', '9.30-19.90'],
          '命中率': ['54.8%', '49.6%', '46.3%', '51%', '55.3%', '46.6%', '48.4%', '49.1%', '46.6%'],
          '命中-三分': ['1.00-3.00', '2.80-8.20', '4.20-11.30', '0.90-2.50', '0.80-2.70', '3.20-9.30', '3.60-9.30', '2.40-7.30', '1.50-4.90'],
          '三分命中率': ['33%', '34.2%', '37.1%', '34.5%', '27.5%', '35%', '38.6%', '33.5%', '30.7%'],
          '命中-罚球': ['10.00-11.70', '7.80-10.50', '8.80-9.60', '9.80-10.90', '7.90-12.20', '7.20-8.40', '4.70-5.40', '3.90-5.10', '6.10-8.10'],
          '罚球命中率': ['85.7%', '74.2%', '91.4%', '90.5%', '64.5%', '85.4%', '86.7%', '76.5%', '74.8%'],
          '场次': [66, 66, 58, 68, 63, 74, 68, 67, 61],
          '上场时间': [34.60, 36.20, 36.30, 35.50, 32.10, 36.90, 35.80, 35.90, 31.90]
      }
      
      df = pd.DataFrame(data)
      
      # 找出出战场次最多的球员
      max_appearances = df['场次'].max()
      player_with_max_appearances = df.loc[df['场次'] == max_appearances, '球员'].values[0]
      
      print("出战场次最多的球员是:", player_with_max_appearances)
      
      # 计算平均出战场次
      average_appearances = df['场次'].mean()
      
      print("所有球员的平均出战场次是:", average_appearances)
      

      输出结果为:

      出战场次最多的球员是: 杰森-塔特姆
      所有球员的平均出战场次是: 64.33333333333333
      

      ###来自你的消息:

      排名球员球队得分命中-出手命中率命中-三分三分命中率命中-罚球罚球命中率场次上场时间
      1乔尔-恩比德76人33.1011.00-20.1054.8%1.00-3.0033%10.00-11.7085.7%6634.60
      2卢卡-东契奇独行侠32.4010.90-22.0049.6%2.80-8.2034.2%7.80-10.5074.2%6636.20
      3达米安-利拉德开拓者32.209.60-20.7046.3%4.20-11.3037.1%8.80-9.6091.4%5836.30
      4谢伊-吉尔杰斯-亚历山大雷霆31.4010.30-20.3051%0.90-2.5034.5%9.80-10.9090.5%6835.50
      5扬尼斯-阿德托昆博雄鹿31.1011.20-20.3055.3%0.80-2.7027.5%7.90-12.2064.5%6332.10
      6杰森-塔特姆凯尔特人30.109.80-21.1046.6%3.20-9.3035%7.20-8.4085.4%7436.90
      7多诺万-米切尔骑士28.3010.00-20.6048.4%3.60-9.3038.6%4.70-5.4086.7%6835.80
      8杰伦-布朗凯尔特人26.6010.10-20.6049.1%2.40-7.3033.5%3.90-5.1076.5%6735.90
      9贾-莫兰特灰熊26.209.30-19.9046.6%1.50-4.9030.7%6.10-8.1074.8%6131.90

      以上这些人谁的出战场次最多?所有人平均出战多少场次?使用sql计算,无需将全部数据重新列举一遍


      ###来自 ChatGPT 的消息:

      根据给出的数据,可以使用SQL查询来计算出战场次最多的球员和平均出战场次。

      出战场次最多的球员可以通过查询最大的场次数来得到:

      SELECT 球员, MAX(场次) AS 最多场次
      FROM 表名;
      

      平均出战场次可以通过查询所有球员的场次数并计算平均值来得到:

      SELECT AVG(场次) AS 平均场次
      FROM 表名;
      

      请将"表名"替换为实际的表名,然后执行上述SQL查询即可得到结果。

      总结一下:

      1. 以上这些人谁的出战场次最多?所有人平均出战多少场次?”这2个问题的答案分别是“杰森塔图姆”和65.67场
      2. 我分别让模型用3种方式输出结果:1-直接输出、2-给出pandas代码后输出、3-只给SQL代码。
      3. 三种方式里,方法1直接错误,两个问题皆错;方法2最后给出答案时,问题2“平均出战场次”算错了。但它给出了正确的pandas代码,执行后两个问题都能得到正确结果;方法3我禁止其输出答案,只给出SQL代码,最后验证sql代码准确无误;
      4. 此外,为了减少大量数据反复传给LLMs增加其负担,实际上可以只给它带表头的2~3行数据,让其明白数据格式即可。

      所以由此可见,与其让它自己推理复杂计算,还不如让它给出代码,然后你自己去执行代码。当然,这里的问题确实是超级简单了,大家可以再试试上难度的统计问题

    • 此外,据了解,OpenAI官方推出的Code Interpreter就是专门干这个的(你可以把它当成个Data Analyzer,感兴趣的童鞋可以试试:OpenAI-Code Interpreter)

5. 总结

本文从实战角度出发,对垂直领域知识库问答这个问题,在Bert时代和LLMs时代的解决方案均做了简述。此外,本文还对LLM时代的LangChain+LLM的方案在实战中出现的问题进行了探讨,最后,还简单尝试了一下ChatGPT在数据分析方面的潜力。

欢迎大家多多点赞关注,一起交流学习吧😊

PS,转载请注明出处哦!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/781423.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【趟坑记录】d3.zoom()的正确使用姿势 @d3.v7

【趟坑记录】d3.zoom()的正确使用姿势 d3.v7 文章目录 【趟坑记录】d3.zoom()的正确使用姿势 d3.v7问题重现原因分析解决方案放缩平移写法特殊修改transform函数的写法 总结 在开发一个D3应用的时候遇到了一个 zoom相关的问题&#xff0c;记录解决思路与方案 问题重现 最近在…

nodejs+vue+elementui学习交流和学习笔记分享系统

Node.js 是一个基于 Chrome JavaScript 运行时建立的一个平台。 前端技术&#xff1a;nodejsvueelementui,视图层其实质就是vue页面&#xff0c;通过编写vue页面从而展示在浏览器中&#xff0c;编写完成的vue页面要能够和控制器类进行交互&#xff0c;从而使得用户在点击网页进…

【Hello mysql】 mysql的事务

Mysql专栏&#xff1a;Mysql 本篇博客简介&#xff1a;介绍mysql的事务 mysql的事务 事务的概念事务功能测试事务的隔离级别如何理解隔离性&#xff08;粗浅理解&#xff09;隔离级别查看和设置隔离级别四种隔离级别详解读 -- 未提交读 - 提交可重复读串行化一致性的理解 总结 …

前端学习——ajax (Day4)

同步代码和异步代码 回调函数地狱和 Promise 链式调用 回调函数地狱 Promise - 链式调用 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge&quo…

python识别极验4滑块验证码实战

闲得无聊&#xff0c;趁着休息研究了一下极验4滑块验证码的安全性&#xff0c;是否有机器识别、自动化拖拽的可能性。首先看一下效果 如何识别验证码 1、下载图片 下载图片可以参考博客《采集极验4滑块验证码图片数据》 2、标记图片 3、标记滑动距离 实现代码 __author__ &…

算法与数据结构(二十一)前缀和数组差分数组

前缀和技巧适用于快速、频繁地计算一个索引区间内的元素之和。 1. 一维数组中的前缀和 先看一道例题&#xff0c;力扣第 303 题「区域和检索 - 数组不可变」&#xff0c;让你计算数组区间内元素的和&#xff0c;这是一道标准的前缀和问题&#xff1a; 题目要求你实现这样一个…

多线程(JavaEE初阶系列2)

目录 前言&#xff1a; 1.什么是线程 2.为什么要有线程 3.进程与线程的区别与联系 4.Java的线程和操作系统线程的关系 5.多线程编程示例 6.创建线程 6.1继承Thread类 6.2实现Runnable接口 6.3继承Thread&#xff0c;使用匿名内部类 6.4实现Runnable接口&#xff0c;使…

nodejs+vue+elementui学生选课系统awwm9

前端技术&#xff1a;nodejsvueelementui,视图层其实质就是vue页面&#xff0c;通过编写vue页面从而展示在浏览器中&#xff0c;编写完成的vue页面要能够和控制器类进行交互&#xff0c;从而使得用户在点击网页进行操作时能够正常。 可以设置中间件来响应 HTTP 请求。 (3) 教…

详细总结Webpack5的配置和使用

打包工具 使用框架&#xff08;React、Vue&#xff09;&#xff0c;ES6 模块化语法&#xff0c;Less/Sass 等 CSS预处理器等语法进行开发的代码要想在浏览器运行必须经过编译成浏览器能识别的 JS、CSS 等语法&#xff0c;才能运行。 所以需要打包工具帮我们做完这些事。除此之…

微信小程序学习笔记(三)——视图与逻辑

页面导航 什么是页面导航 页面导航指的是页面之间的相互跳转。例如&#xff0c;浏览器中实现页面导航的方式有如下两种&#xff1a; <a> 链接location.href 小程序中实现页面导航的两种方式 声明式导航、 在页面上声明一个 <navigator> 导航组件通过点击 <…

R语言手动安装包

包安装问题解决方案 1. Biocmanager安装 2. 手动安装 文章目录 包安装问题解决方案前言一、Rstudio手动安装二、conda手动安装R包2.1 在Linux环境中使用R2.2 anaconda官网包下载 总结 前言 大家好✨&#xff0c;这里是bio&#x1f996;。点赞关注不迷路。在上一篇blog中为大家…

Tabby - 本地化AI代码自动补全 - Linux Debian

参考&#xff1a; https://github.com/TabbyML/tabby Docker | Tabby Linux Debian上快速安装Docker并运行_Entropy-Go的博客-CSDN博客 Tabby - 本地化AI代码自动补全 - Windows10_Entropy-Go的博客-CSDN博客 为什么选择Tabby 已经有好几款类似强劲的代码补全工具&#xf…

自动驾驶感知系统-摄像头

车载摄像头的工作原理&#xff0c;首先是采集图像&#xff0c;将图像转换为二维数据&#xff1b;然后&#xff0c;对采集的图像进行模式识别&#xff0c;通过图像匹配算法识别行驶过程中的车辆、行人、交通标识等&#xff1b;最后&#xff0c;依据目标物体的运动模式或使用双目…

(202307)wonderful-sql:基础查询与排序(task2)

教程链接&#xff1a;Datawhale - 一个热爱学习的社区 知识学习 前提&#xff1a; 上一次任务中提出了本课程的用表&#xff0c;但是我并没有加入这个表&#xff0c;这次学习前先对这个表进行插入。 INSERT INTO product VALUES(0001, T恤衫, 衣服, 1000, 500, 2009-09-20)…

[Linux笔记]gdb调试器常用指令

gcc/g形成的可执行程序默认是release版的。若要生成debug版&#xff0c;应使用-g选项。 如&#xff1a;gcc -o mytest test.c -g -stdc99 可以看到debug版包含了调试信息&#xff1a; 使用&#xff1a;gdb 文件名&#xff1a; 补充&#xff1a; 以下所有的查看指令都不会影…

CMU 15-445 -- Parallel Execution - 11

CMU 15-445 -- Join Algorithms - 11 引言Parallel & DistributedInter-query vs. Intra-query Parallelism Process ModelApproach #1: Process per DBMS WorkerApproach #2: Process PoolApproach #3: Thread per DBMS Worker Execution ParallelismInter-query Parallel…

基于SpringBoot+vue的滴答拍摄影项目设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

JAVA设计模式——23种设计模式详解

一、什么是设计模式&#x1f349; 设计模式&#xff08;Design pattern&#xff09; 是解决软件开发某些特定问题而提出的一些解决方案也可以理解成解决问题的一些思路。通过设计模式可以帮助我们增强代码的可重用性、可扩充性、 可维护性、灵活性好。我们使用设计模式最终的目…

基于物联网网关的工业数据可视化平台有什么功能?

随着数字化浪潮的不断发展&#xff0c;工业数据的价值越来越重要。在企业利用数据的过程中&#xff0c;数据可视化是数字化系统中十分重要的一部分。然而&#xff0c;工厂多种设备、多种协议影响到系统的搭建使得企业无法获得全面的数据视图&#xff0c;也无法对整个生产流程进…

Ubuntu22.04 安装深度学习服务器全纪录

文章目录 Ubuntu 22.04 安装深度学习服务器全纪录1. 制作启动盘2. 安装 Ubuntu 22.043.配置国内镜像软件源4. Python 相关设置5. 配置 SSH6. 配置远程桌面6. 安装 CUDA7. 安装 docker8. 安装 Anaconda9. 安装 ChatGLM210. 使用 fastllm 推理加速 Ubuntu 22.04 安装深度学习服务…