知识库问答LangChain+LLM的二次开发:商用时的典型问题及其改进方案

前言

如之前的文章所述,我司下半年成立大模型项目团队之后,我虽兼管整个项目团队,但为让项目的推进效率更高,故分成了三大项目组

  • 第一项目组由霍哥带头负责类似AIGC模特生成系统
  • 第二项目组由阿荀带头负责论文审稿GPT以及AI agent项目
  • 第三项目组由朝阳带头负责企业多文档的知识库问答系统,朝阳、猫药师、bingo等人贡献了本文的一半以上

对于知识库问答,现在有两种方案,一种基于llamaindex,一种基于langchain +LLM

考虑到我已在此文《基于LangChain+LLM的本地知识库问答:从企业单文档问答到批量文档问答》中详细介绍了langchain、以及langchain-ChatGLM项目的源码剖析,本文重点则阐述如何通过基于langchain-chatchat二次开发一个知识库问答系统,包括其商用时的典型问题以及对应的改进方案,包括且不限于

  1. 如何解决检索出错:embedding算法是关键之一
  2. 如何解决检索对了但不根据知识库回答而是根据模型自有的预训练知识回答
  3. 如何解决非结构化文档分割不够准确的问题:比如最好按照语义切分
  4. 如何针对结构化文档采取更好的chunk分割:基于规则
  5. 如何确保召回结果的全面性与准确性:多路召回与最后的去重/精排
  6. 如何解决基于文档中表格的问答
  7. 更多问题的解决暂在我司的「大模型项目开发线上营」里见,至于本文则后续更新

前置部分 知识库的构建

将七月近两年整理的大厂面试题PDF文件作为源文件来进行知识库的构建

默认使用RapidOCRPDFLoader作为文档加载器

RapidOCR是目前已知运行速度最快、支持最广,完全开源免费并支持离线快速部署的多平台多语言OCR。由于PaddleOCR工程化不是太好,RapidOCR为了方便大家在各种端上进行OCR推理,将PaddleOCR中的模型转换为ONNX格式,使用Python/C++/Java/Swift/C# 将它移植到各个平台


更多详情参考:https://rapidai.github.io/RapidOCRDocs/docs/overview/

另,本文里的测试及二次开发主要针对langchain-chatchat的V0.2.6版本,资源及相关默认配置如下:

  • 显卡:Tesla P100,16G(显存)
  • 分词器:ChineseRecursiveTextSplitter
  • chunk_size:250
  • embedding模型:m3e-base
  • LLM模型:chatglm2-6b
  • 向量库:faiss

第一部分 如何解决检索的问题:比如检索出错等

1.1 如何解决检索出错:embedding算法是关键之一

1.1.1 问题描述:检索出的结果与问题不相关、甚至检索不到

使用原始的langchain-chatchat V0.2.6版本,会出现检索出的部分结果与问题相关性不大的情况,甚至还会出现对某些问题检索不到的情况

比如问一个面试题:用通俗的语言介绍下强化学习?检索得到的内容如下:

出处 [1] 2022Q2大厂面试题共92题(含答案及解析).pdf

CART 树算法的核心是在生成过程中用基尼指数来选择特征。 4、用通俗的语言介绍下强化学习(Reinforcement Learning)监督学习的特点是有一个“老师”来“监督”我们,告诉我们正确的结果是什么。在我们在小的时候,会有老师来教我们,本质上监督学习是一种知识的传递,但不能发现新的知识。对于人类整体而言,真正(甚至唯一)的知识来源是实践——也就是强化学习。比如神农尝百草,最早人类并不知道哪些草能治病,但是通 过尝试,就能学到新的知识。学习与决策者被称为智能体,与智能体交互的部分则称为环境。智能体与环境不断进行交互,具体而言,这一交互的过程可以看做是多个时刻,每一时刻,智能体根据环境的状态,依据一定的策略选择一个动作(这


出处 [2] 2021Q3大厂面试题共107题(含答案及解析).pdf

20.2 集成学习的方式,随机森林讲一下,boost 讲一下, XGBOOST 是怎么回事讲一下。 集成学习的方式主要有 bagging,boosting,stacking 等,随机森林主要是采用了 bagging 的思想,通过自助法(bootstrap)重采样技术,从原始训练样本集 N 中有放回地重复随机抽取 n 个样本生成新的训练样本集合训练决策树,然后按以上步骤生成 m 棵决策树组成随机森林,新数据的分类结果按分类树 投票多少形成的分数而定。 boosting是分步学习每个弱分类器,最终的强分类器由分步产生的分类器组合而成,根据每步学习到的分类器去改变各个样本的权重(被错分的样本权重加大,反之减小) 它是一种基于 boosting增强策略的加法模型,训练的时候采用前向分布算法进行贪婪的学习,每次迭代


出处 [3] 2022Q2大厂面试题共92题(含答案及解析).pdf

特征工程可以并行开发,大大加快开发的速度。 训练速度较快。分类的时候,计算量仅仅只和特征的数目相关。 缺点:准确率欠佳。因为形式非常的简单,而现实中的数据非常复杂,因此,很难达到很高的准确性。很难处理 数据不平衡的问题。 3、介绍下决策树算法常见的决策树算法有三种:ID3、C4.5、CART 树 ID3 算法的核心是在决策树的每个节点上应用信息增益准则选择特征,递归地构架决策树。C4.5 算法的核心是在生成过程中用信息增益比来选择特征。 CART 树算法的核心是在生成过程中用基尼指数来选择特征。4、用通俗的语言介绍下强化学习(Reinforcement Learning)

可以看出

  1. 第一个检索结果和问题是相关的
  2. 第二个检索结果和问题是完全没关系的
  3. 而第三个检索结果的最后一句话是和问题相关的

再比如问一个面试题:Bert的预训练过程是什么?

  • 检索得到的内容如下:

    出处 [1] 2021Q2大厂面试题共121题(含答案及解析).pdf

    成. 15.6 bert 的改进版有哪些 参考答案: RoBERTa:更强大的 BERT 加大训练数据 16GB -> 160GB,更大的batch size,训练时间加长 不需要 NSP Loss: natural inference 使用更长的训练 SequenceStatic vs. Dynamic Masking 模型训练成本在 6 万美金以上(估算) ALBERT:参数更少的 BERT一个轻量级的 BERT 模型 共享层与层之间的参数 (减少模型参数)


    出处 [2] 2022Q1大厂面试题共65题(含答案及解析).pdf

    可以从预训练方法角度解答。
    … 20
    5、RoBERTa 相比 BERT 有哪些改进?

    20 6、BERT 的输入有哪几种 Embedding?


    出处 [3] 2022Q2大厂面试题共92题(含答案及解析).pdf

    保证模型的训练,pre-norm 显然更好一些。 5、GPT 与 Bert 的区别 1) GPT
    是单向模型,无法利用上下文信息,只能利用上文;而 BERT 是双向模型。 2) GPT 是基于自回归模型,可以应用在 NLU 和 NLG两大任务,而原生的 BERT 采用的基于自编码模 型,只能完成 NLU 任务,无法直接应用在文本生成上面。 6、如何加速 Bert模型的训练 BERT 基线模型的训练使用 Adam with weight decay(Adam 优化器的变体)作为优化器,LAMB 是一款通用优化器,它适用于小批量和大批量,且除了学习率以外其他超参数均无需调整。LAMB 优化器支持自

  • 而在文档中的结果如下:

可以看出,是没有检索到的相关内容的

1.1.2 可能的原因分析与优化方法

使用默认配置时,虽然上传文档可以实现基础的问答,但效果并不是最好的,通常需要考虑以下几点原因

  1. 文件解析及预处理:对于PDF文件,可能出现解析不准确的情况,导致检索召回率低;
  2. 文件切分:不同的chunk_size切分出来的粒度不一样。如果设置的粒度太小,会出现信息丢失的情况;如果设置的粒度太大,又可能会造成噪声太多,导致模型输出的结果明显错误。且单纯根据chunk_size切分比较简单粗暴,需要根据数据进行针对性优化;
  3. embedding 模型效果:模型效果不好也会影响检索结果

优化方法:

  • 文件解析及预处理
    一方面可以尝试不同的PDF解析工具,解析更加准确
    另一方面可以考虑将解析后的内容加上标题,并保存成Markdown格式,这样可以提高召回率
  • 文件切分
    基于策略:对于特定的文档,比如有标题的,可以优先根据标题和对应内容进行划分,再考虑chunk_size
    基于语义分割模型:还可以考虑使用语义分割模型
  • 模型效果
    尝试使用更多embedding模型,获得更精确的检索结果。如:piccolo-large-zh 或 bge-large-zh-v1.5等等。可以参考榜单:https://huggingface.co/spaces/mteb/leaderboard
  • 向量库
    如果知识库比较庞大(文档数量多或文件较大),推荐使用pg向量数据库
    如果文件中存在较多相似的内容,可以考虑分门别类存放数据,减少文件中冲突的内容
  • 多路召回
    结合传统方法进行多路召回
  • 精排
    对多路召回得到的结果进行精排

1.2 如何根据业务场景确定最合适的embedding算法

1.2.1 《MTEB: Massive Text Embedding Benchmark(海量文本嵌入基准)》

判断哪些文本嵌入模型效果较好,通常需要一个评估指标来进行比较,《MTEB: Massive Text Embedding Benchmark(海量文本嵌入基准)》就是一个海量文本嵌入模型的评估基准

  • 论文地址:https://arxiv.org/abs/2210.07316
    MTEB包含8个语义向量任务,涵盖58个数据集和112种语言。通过在MTEB上对33个模型进行基准测试,我们建立了迄今为止最全面的文本嵌入基准。我们发现没有特定的文本嵌入方法在所有任务中都占主导地位。这表明该领域尚未集中在一个通用的文本嵌入方法上,并将其扩展到足以在所有嵌入任务上提供最先进的结果
  • github地址:https://github.com/embeddings-benchmark/mteb#leaderboard

榜单地址:https://huggingface.co/spaces/mteb/leaderboard

1.2.2 中文海量文本embedding任务排行榜

从Chinese Massive Text Embedding Benchmark中可以看到目前最新的针对中文海量文本embedding的各项任务的排行榜,针对不同的任务场景均有单独的排行榜。

任务榜单包括:

  • Retrieval
  • STS
  • PairClassification
  • Classification
  • Reranking
  • Clustering

其中,在本地知识库任务中,主要是根据问题query的embedding表示到向量数据库中检索相似的本地知识文本片段。因此,该场景主要是Retrieval检索任务。检索任务榜单如下:

目前检索任务榜单下效果最好的是bge系列的bge-large-zh模型,langchain-chatchat项目中默认的m3e-base也处于比较靠前的位置

1.3 中文检索效果比较突出的:bge与m3e模型

1.3.1 bge模型的简介

BGE是北京智源人工智能研究院发布的中英文语义向量模型

  • bge模型:https://huggingface.co/BAAI/bge-large-zh
  • bge项目:https://github.com/FlagOpen/FlagEmbedding/blob/master/README_zh.md

以下是BGE的技术亮点

  1. 高效预训练和大规模文本微调;
  2. 在两个大规模语料集上采用了RetroMAE预训练算法,进一步增强了模型的语义表征能力;
  3. 通过负采样和难负样例挖掘,增强了语义向量的判别力;
  4. 借鉴Instruction Tuning的策略,增强了在多任务场景下的通用能力
1.3.1.1 RetroMAE
  • RetroMAE论文:https://arxiv.org/abs/2205.12035
  • 博客:BGE登顶MTEB的神器--RetroMAE|一种基于自动编码的检索模型预训练方法 - 知乎

目前主流的语言模型的预训练任务都是token级别的,比如MLM或者Seq2Seq,但是这种训练任务难以让模型获得一个高质量的基于句子级别的句向量,这限制了语言模型在检索任务上的潜力。针对这个弊端,目前有两者针对检索模型的预训练策略

  • 第一种是self-contrastive learning,这种方式往往受限于数据增强的质量,并且需要采用非常庞大数量的的负样本
  • 另一种基于anto-encoding,一种自重建方法,不受数据增强跟负样本采样策略的影响,基于这种方法的模型性能好坏有两个关键因素,其一是重建任务必须要对编码质量有足够的要求,其二是训练数据需要被充分利用到

基于此,研究人员提出了RetraoMAE,它包括两个模块,其一是一个类似于BERT的编码器,用于生成句向量,其二是一个一层transformer的解码器,用于重建句子

  • Encoding
    给定一个句子输入X,随机mask掉其中一小部分token后得到X_enc,这里通常会采用中等的mask比例(15%~30%),从而能保留句子原本大部分的信息,然后利用一个编码器对其进行编码,得到对应的的句向量h_x。由于采用了类似BERT的编码器,最终将[CLS]位置最后一层的隐状态作为句子向量
  • Decoding
    给定一个句子输入X,随机mask掉其中一部分token得到X_dec,这里通常会采取比encoder部分更加激进的mask比例(50%~70%),利用mask后的文本跟encoder生成的句向量对文本进行重建
    在解码器部分采用了及其简单的网络结构跟非常激进的mask比例,从而使得解码任务变得极具挑战性,迫使encoder去生成高质量的句向量才能最终准确地完成原文本重建
  • Enhanced Decoding
    前面提及的解码策略有一种缺陷,就是训练信号只来源于被mask掉的token,而且每个mask掉的token都是基于同一个上下文重建的。于是研究人员提出了一种新的解码方法,Enhanced Decoding,具体做法如下
    a) 首先生成两个不同的输入流H1(query)跟H2(context)

    b) 通过attention机制得到新的输出A,这里的M是一个mask矩阵,第i个token所能看得到的其他token是通过抽样的方式决定的(当然要确保看不到自身token,而且都要看得见第一个token,也就是encoder所产出CLS句向量的信息)

    c)最终利用A跟H1去重建原文本,这里重建的目标不仅仅是被mask掉的token,而是全部token。

最终RetroMAE的损失由两部分相加得到,其一是encoder部分的MLM损失,其二是deocder部分自重建的交叉熵损失。

1.3.2.2 bge模型的微调
  • ​微调脚本:https://github.com/FlagOpen/FlagEmbedding/tree/master/examples/finetune
  • 数据格式
    {"query": str, "pos": List[str], "neg":List[str]}
  • 难负样本挖掘
    难负样本是一种广泛使用的提高句子嵌入质量的方法。可以按照以下方法挖掘难负样本
    python -m FlagEmbedding.baai_general_embedding.finetune.hn_mine \
    --model_name_or_path BAAI/bge-base-en-v1.5 \
    --input_file toy_finetune_data.jsonl \
    --output_file toy_finetune_data_minedHN.jsonl \
    --range_for_sampling 2-200 \
    --use_gpu_for_searching
  • 训练
    python -m FlagEmbedding.baai_general_embedding.finetune.hn_mine \
    --model_name_or_path BAAI/bge-base-en-v1.5 \
    --input_file toy_finetune_data.jsonl \
    --output_file toy_finetune_data_minedHN.jsonl \
    --range_for_sampling 2-200 \
    --use_gpu_for_searching

1.3.2 m3e模型

  • m3e-base模型:https://huggingface.co/moka-ai/m3e-base
  • m3e项目:GitHub - wangyingdong/m3e-base
1.3.2.1 m3e模型简介

M3E使用in-batch负采样的对比学习的方式在句对数据集进行训练,为了保证in-batch负采样的效果,使用A100来最大化batch-size,并在共计2200W+的句对数据集上训练了 1 epoch

使用了指令数据集,M3E 使用了300W+的指令微调数据集,这使得 M3E 对文本编码的时候可以遵从指令,这部分的工作主要被启发于 instructor-embedding

基础模型,M3E 使用 Roberta 系列模型进行训练

1.3.2.2 m3e模型微调
  • 微调脚本:
    m3e是使用uniem脚本进行微调
    from datasets import load_dataset
    
    from uniem.finetuner import FineTuner
    
    dataset = load_dataset('shibing624/nli_zh', 'STS-B')
    # 指定训练的模型为 m3e-small
    finetuner = FineTuner.from_pretrained('moka-ai/m3e-small', dataset=dataset)
    finetuner.run(epochs=3)

详细代码暂放在「大模型项目开发线上营」中,至于本文后续更新

第二部分 如何解决检索对了但不根据知识库回答而是根据模型自有的预训练知识回答

2.1 开源LLM并没有完全根据文档内容来回答,而是基于自己的知识进行了相应回答

LLM问题主要有以下几点:

  1. LLM的回答会出现遗漏信息或补充多余信息的情况
  2. chatglm2-6b还会出现回答明显错误的情况

比如我们还用上面的一个面试题:用通俗的语言介绍下强化学习

  • LLM基于知识库给的答案如下:

    强化学习是一种人工智能技术,它通过不断地试错和学习,使机器逐步掌握如何在特定环境中实现某种目标。与监督学习不同,强化学习没有一个“老师”来指导机器,而是通过与环境的交互来不断学习。


    在强化学习中,机器作为一个智能体,与环境的交互过程可以看作是多个时刻的循环。在每个时刻,机器根据当前的环境状态,依据一定的策略选择一个动作,然后接着得到一个反馈(如得分或奖励)。机器通过不断试错和学习,逐渐提高自己的策略,以最大化累积的奖励。


    强化学习算法主要有三种:ID3、C4.5和CART树。其中,ID3算法通过信息增益准则来选择特征,C4.5算法则用信息增益比来选择特征,而CART树算法则是用基尼指数来选择特征。这些算法都在决策树的生成过程中应用某种准则来选择特征,以达到提高模型性能的目的

  • 而在文档中的结果如下:

可以看出,LLM并没有完全根据文档内容来回答,而是基于自己的知识进行了相应回答,而对于回答的第三段话,强化学习算法主要有三种:ID3、C4.5和CART树。可以看出,这段话的表达是完全错误的

2.2 LLM不按照知识库回答的优化方法

  • 优化prompt,可能会有一定效果的。但由于随机性,结果并不能得到保证
  • 优先使用最新的6B/7B模型:ChatGLM3-6B、Baichuan2-7B、Qwen-7B,如果资源可以支持48G以上的显卡,可以考虑使用Qwen-14B-Chat 或 Baichuan-13B-Chat,13B的模型通常好于6B/7B模型
  • PDF文档解析优化方案,下文3.2节详述

第三部分 非结构化文档与结构化文档的典型问题:如何更好分割

3.1 如何解决非结构化文档分割不够准确的问题:比如最好按照语义切分

// 待更

3.2 如何针对结构化文档采取更好的chunk分割:基于规则

3.2.1 先解析PDF,然后分别获取文本内容和图片内容,最后拼接文本内容和图片内容

Langchian-Chatchat中对于不同类型的文件提供了不同的处理方式,从项目server/knoledge_base/utils.py文件中可以看到对于不同类型文件的加载方式,大体有HTML,Markdown,json,PDF,图片及其他类型等

LOADER_DICT = {"UnstructuredHTMLLoader": ['.html'],
               "UnstructuredMarkdownLoader": ['.md'],
               "CustomJSONLoader": [".json"],
               "CSVLoader": [".csv"],
               # "FilteredCSVLoader": [".csv"], # 需要自己指定,目前还没有支持
               "RapidOCRPDFLoader": [".pdf"],
               "RapidOCRLoader": ['.png', '.jpg', '.jpeg', '.bmp'],
               "UnstructuredFileLoader": ['.eml', '.msg', '.rst',
                                          '.rtf', '.txt', '.xml',
                                          '.docx', '.epub', '.odt',
                                          '.ppt', '.pptx', '.tsv'],
               }

这里,我们重点关注PDF文件的解析方式,并探究其可能的优化方案。从上面的文件加载字典中可以看出,PDF文件使用的加载器为RapidOCRPDFLoader,该文件的方法在项目document_loaders/mypdfloader.py中

处理方法:

  1. 首先使用fitz(即pyMuPDF)的open方法解析PDF文件;
  2. 对于每一页的文本内容,通过get_text方法进行获取,而对于图片内容通过get_images方法进行获取,获取后通过RapidOCR对图片中的文本内容进行提取;
  3. 最后将从图片中提取的文本和原始的文本内容进行拼接,得到最终的所有文本内容。然后进行下一步的分词和文本切割。

这种方式的优点简单粗暴,基本上对于任何排版的PDF文件都能够提取到有效信息。但缺点也很明显,就是无差别,比如我们的文档本身就有较好结构,提取出来的内容也无法将结构反映出来。所以,通常情况下需要根据文档的具体情况对解析后的文档做进一步定制化处理

3.2.2 针对结构化文档本身的特点:针对性分割

3.2.2.1 七月在线大厂面试题PDF文档特点

以七月在线大厂面试题PDF文档为例,有以下特点:

  1. 文档具有书签,可以直接根据书签对应到具体的页码
  2. 文档结构不复杂,共有两级标题,一级标题表示一个大的章节,二级标题表示面试题的问题,文本内容为每道面试题对应的答案;
  3. 每道面试题是独立的,和其前后的面试题并没有明显的相关性。
  4. 面试题题目的长度长短不一,短的有几个词组成,长的基本一句话。
  5. 文档中除中文外,还有大量模型或算法英文词,且文档中包含部分公式和代码

因此,可以考虑根据文档的标题进行分割,即将文档中的标题和标题对应的内容分为一块,在放入向量库的时候可以尝试两种方式,一种是只将题目进行向量化表示存入向量库,另一种是将题目和答案一起进行向量化表示存入向量库

3.2.2.2 PDF文档解析可选方案

对此,尝试了几种PDF解析工具包:pdfplumber、PyPDF2、fitz(PyMuPDF)

  • 通过fitz获取书签信息,得到面试题题目与其所在的页码,保存为一个字典;
  • 尝试用pdfplumber、PyPDF2、fitz抽取每一页的文本信息,与字典中的标题进行匹配(使用find方法)
  • 通过面试题当前位置和下一个面试题位置(这里的位置指的是索引),对面试题进行分块;
  • 最后,输出面试题与其对应的答案
3.2.2.3 PDF文档解析存在问题

文档解析过程中存在的问题:

  1. 书签中的标题内容和文档中的标题内容并不完全一致,这种情况可能是解析后出现多余的空格导致的
  2. 需要考虑一道面试题可能存在跨页的情况,一般是会出现一道面试题出现在两页的情况,但也需要考虑一道面试跨三页或多页的情况
  3. 由于一级标题是有分页符的,每个一级标题会另起一页,因此在处理时也需要考虑此种情况。
  4. 解析的文本中带有页脚,如:第 4 页 共 46 页,由于页脚的内容对面试题是没有意义的,因此也需要考虑去掉
3.2.2.4 PDF文档解析解决方案

解决方案:

  1. 对于书签中的标题内容和文档中的标题内容并不完全一致的问题,一种方式有考虑去除文档中标题的空格,实现困难在于无法精确定位,如果全去掉就会出现一些英文单词拼接在一块的情况,可能对语义或后续的检索产生影响;一种方式是不去除,如果出现这种情况,则将标题所在页的信息都提取出来;
  2. 对于一道面试题可能存在跨页的情况,可以通过设置起始页和终止页,对相邻标题(主要是下一个标题)所在页进行判断的方式来处理;
  3. 对于每个一级标题会另起一页的情况,可以通过添加对特殊字符“1、”判断的方式来处理;
  4. 对于页脚,可以使用正则表达式进行匹配去除
3.2.2.5 效果

具体解析结果暂见我司「大模型项目开发线上营」中的代码

测试效果:
以2022Q2大厂面试题共92题(含答案及解析).pdf文件为例,共92道面试题

匹配不到的数量
pdfplumber:30
PyPDF2:20(解析过程中,英文词之间的空格会消失,如selfattention)
fitz:35

第四部分 让召回结果更全面、准确,及基于表格的问答

4.1 如何确保召回结果的全面性与准确性:多路召回与最后的去重/精排

// 待更

4.2 如何解决基于文档中表格的问答

// 待更

参考文献与推荐阅读

  1. 我司第三项目组带头人朝阳的笔记:基于Langchain-Chatchat的知识库问答系统
  2. Text embedding 模型总结
  3. ..

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在 Windows 中安装 SQLite 数据库

在 Windows 上安装 SQLite 步骤1 请访问 SQLite 下载页面,从 Windows 区下载预编译的二进制文件 ​ 步骤2 您需要下载 sqlite-dll-win-x64-3440200.zip 和 sqlite-tools-win-x64-3440200.zip 压缩文件 步骤3 创建文件夹 C:\Program Files\SQLite,并在…

PHP的Laravel的数据库迁移

1.默认迁移文件 2.数据库迁移 在终端输入以下代码 php artisan migrate 我的报错啦!!!!! 数据库里面只有两张表,实际上应该有四张的!!! 解决方法: 反正表已…

Modbus RTU转Modbus TCP模块,RS232/485转以太网模块,YL102 多功能串口服务器模块

特点: ● Modbus RTU协议自动转换成Mobus TCP协议 ● 100M高速网卡,10/100M 自适应以太网接口 ● 支持 AUTO MDI/MDIX,可使用交叉网线或平行网线连接 ● RS232波特率从300到256000可设置 ● 工作方式可选择TCP Server, TCP Client, U…

【Leetcode】重排链表、旋转链表、反转链表||

目录 💡重排链表 题目描述 方法一: 方法二: 💡旋转链表 题目描述 方法: 💡反转链表|| 题目描述 方法: 💡总结 💡重排链表 题目描述 给定一个单链表 L 的头节…

位移贴图、凹凸贴图和法线贴图之间的差异

在线工具推荐: 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 这三种类型的贴图中的每一种都会在几何体表面上创建看起来像其他分辨…

uniApp中uView组件库的丰富布局方法

目录 基本使用 #分栏间隔 #混合布局 #分栏偏移 #对齐方式 API #Row Props #Col Props #Row Events #Col Events UniApp的uView组件库是一个丰富的UI组件库,提供了各种常用的UI组件和布局方法,帮助开发者快速构建美观、灵活的界面。下面给你写一…

(windows2012共享文件夹和防火墙设置

windows2012共享文件夹和防火墙设置 1.windows2012文件夹共享1.共享和高级共享的区别![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/0d815cc6862a4c7a99be11442fb5d950.png#pic_center) 2.windows的防火墙设置1.防火墙设置8080端口让tomot可以在主机可以访问1.新建…

Switch语句与链接—计算机系统基础

实验内容:修改二进制可重定位目标文件“phase1.o”中相关节的内容(注意不允许修改.text节和重定位节的内容),使其与main.o模块如下链接后运行时输出目标字符串“123456789” gcc -no-pie -o linkbomb main.o phase1.o ./linkbomb…

Pandas的datetime数据类型

Python的datetime对象 Python内置了datetime对象,可以在datetime库中找到 from datetime import datetime now datetime.now() now 还可以手动创建datetime t2 datetime(2023,4,21) now-t2 # datetime.timedelta(days251, seconds31427, microseconds546921)将…

C# WPF上位机开发(MVVM模式开发)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 学习过vue的同学都知道mvvm这个名词。从字面上理解,可能有点拗口,但是我们可以去理解一下它的优点是什么。mvc相信大家都明…

生产系统稳定上线600天!中国联通CUDB for OceanBase的开源共建和规模化应用

中国联通软件研究院架构部平台承载了上千应用的数据库需求,并且现存大量数据库使用过程缺少规范、缺少监控,同时还存在着数据库核心技术相关风险。为了实现核心技术自主可控,及时为用户解决线上问题、满足用户的功能需求,提供物美…

GIT提交、回滚等基本操作记录

1、add文件时warning: LF will be replaced by CRLF in .idea/workspace.xml. 原因:windows中的换行符为 CRLF, 而在Linux下的换行符为LF,所以在执行add . 时会出现以下提示 解决:git config core.autocrlf false 2、GIT命令&…

【数据库系统概论】第4章-数据库安全性

复习用,别看了 文章目录 4.1 计算机安全性概述4.2 数据库安全性控制4.2.1 用户标识和鉴定4.2.2 存取控制4.2.3 自主存取控制方法4.2.4 数据库角色4.2.5 强制存取控制 4.3 视图机制4.4 审计4.5 数据加密4.6 其他安全性保护 4.1 计算机安全性概述 不安全因素 4.2 …

gin框架使用系列之五——表单校验

系列目录 《gin框架使用系列之一——快速启动和url分组》《gin框架使用系列之二——uri占位符和占位符变量的获取》《gin框架使用系列之三——获取表单数据》《gin框架使用系列之四——json和protobuf的渲染》 一 、表单验证的基本理论 在第三篇中,我们介绍了如何…

linux系统 CentOS Tomcat 部署论坛

jdk安装命令:yum -y install java-1.8.0-openjdk-devel.x86_64 结尾上显示下图为成功 检查jdk环境是否配置成功命令:java -version或javac 显示版本 显示信息 mysql安装: 检查是否存mariadb数据库:rpm -qa | grep mariad 卸载ma…

Elasticsearch中复制一个索引数据到新的索引中

问题 我有时候,需要调试一个已经存在的ES索引,需要从已有的索引复制数据到新的索引中去。 解决 这里我借助一个GUI工具,来解决这个问题,底层它是使用Reindex的API实现索引数据复制的。利用Reindex API搞不定这个事情&#xff0…

【MATLAB】PSO粒子群优化BiLSTM(PSO_BiLSTM)的时间序列预测

有意向获取代码,请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 基于PSO粒子群优化的BiLSTM的时间序列预测算法的基本原理如下: 「双向长短时记忆(BiLSTM)模型」:这是一种深度学习模型,特别适用…

C#编程艺术:Fizzler库助您高效爬取www.twitter.com音频

数据是当今数字时代的核心资源,但是从互联网上抓取数据并不容易。本文将教您如何利用C#编程艺术和Fizzler库高效爬取Twitter上的音频数据,让您轻松获取所需信息。 Twitter简介 Twitter是全球最大的社交媒体平台之一,包含丰富的音频资源。用…

【TensorFlow 精简版】TensorFlow Lite

目录 一 TensorFlow Lite简介 二 开发 三 开始使用 一 TensorFlow Lite简介 TensorFlow Lite 是一组工具,可帮助开发者在移动设备、嵌入式设备和 loT 设备上运行模型,以便实现设备端机器学习。 针对设备端的机器学习进行的优化: ① 延时&…

WPF+Halcon 培训项目实战(1-5):Halcon安装,图像处理,Halcon简单模板匹配

文章目录 前言相关链接项目专栏我个人对就业市场的评价Halcon安装实战1-4:Halcon基础实战5:模板匹配[形状匹配]实战代码 结尾 前言 为了更好地去学习WPFHalcon,我决定去报个班学一下。原因无非是想换个工作。相关的教学视频来源于下方的Up主…