LangChain +Streamlit+ Llama :将对话式人工智能引入您的本地设备成为可能(上篇)

news2024/11/23 19:15:55

🦜️ LangChain +Streamlit🔥+ Llama 🦙:将对话式人工智能引入您的本地设备🤯

将开源LLMs和LangChain集成以进行免费生成式问答(不需要API密钥)

在过去的几个月中,大型语言模型(LLMs)得到了广泛的关注,吸引了全球开发者的兴趣。这些模型为正在开发聊天机器人、个人助理和内容创作的开发者带来了令人兴奋的前景。LLMs带来的可能性在开发者|人工智能|自然语言处理社区引发了热潮。

什么是LLMs?

大型语言模型(LLM)是指能够产生与人类语言密切相似并以自然方式理解提示的机器学习模型。这些模型使用包括书籍、文章、网站和其他来源的大量数据集进行训练。通过分析数据中的统计模式,LLM预测给定输入后最可能出现的词语或短语。

最近几年LLM的时间线: 《大型语言模型综述》[1]

图片链接:

通过利用大型语言模型(LLM),我们可以有效地利用领域特定数据来解决问题。当处理模型在初始训练期间无法访问的信息时,例如公司的内部文件或知识库,这将特别有优势。

为此目的使用的架构称为“检索增强生成”或者更常见的“生成式问答”。

LangChain是什么🦜🔗?

LangChain是一个令人印象深刻并且免费提供的框架,精心设计用于让开发者利用语言模型,尤其是大型语言模型(LLM)来创建应用程序。

LangChain革命性地改变了各种应用程序(包括聊天机器人、生成式问答和摘要)的开发过程。通过无缝地将来自多个模块的组件链接在一起,LangChain使得能够根据LLMs的威力创建出出色的应用程序。

了解更多:官方文档

https://python.langchain.com/v0.1/docs/get_started/introduction.html

动机?

在本文中,我将演示从零开始创建自己的文档助手的过程,利用LLaMA 7b和LangChain,这是一个专门为与LLMs无缝集成而开发的开源库。

以下是博客结构的概述,列出了将对流程进行详细分解的特定部分:

1.设置虚拟环境和创建文件结构

2.将LLM安装到本地机器

3.将LLM与LangChain集成并自定义PromptTemplate

4.文档检索和答案生成

5.使用Streamlit构建应用程序

第一部分:设置虚拟环境和创建文件结构

设置虚拟环境为运行应用程序提供了一个受控且隔离的环境,确保其依赖与其他系统范围的软件包分离。这种方法简化了依赖管理,并帮助在不同环境之间保持一致性。

为了设置这个应用程序的虚拟环境,我会在我的GitHub存储库中提供pip文件。首先,我们根据图中所示,创建必要的文件结构。或者,您可以直接克隆存储库以获取所需的文件。

在models文件夹内,我们将存储我们将要下载的LLMs,而pip文件将位于根目录中。要在虚拟环境中创建并安装所有依赖项,可以在相同的目录下使用 pipenv install 命令,或者简单地运行 ⚙️setup_env.bat 批处理文件。它将从 pipfile 中安装所有依赖项。这将确保所有必要的软件包和库都已安装在虚拟环境中。一旦成功安装了依赖项,我们可以继续下一步,即下载所需的模型。这是存储库链接👇:

GitHub - afaqueumer/DocQA: Question Answering with Custom FIles using LLMs

第二部分:在本地计算机上获取LLaMA

什么是LLaMA?

LLaMA是由Meta AI设计的一种新的大型语言模型,Meta AI是Facebook的母公司。LLaMA拥有从70亿到650亿参数的多样化模型集合,是目前最综合的语言模型之一。于2023年2月24日,Meta将LLaMA模型发布给公众,以展示他们对开放科学的承诺。

图片来源: LLaMA[4]

考虑到LLaMA的显著能力,我们决定利用这个强大的语言模型来实现我们的目标。具体而言,我们将使用LLaMA的最小版本,即LLaMA 7B。即使在这个较小的规模下,LLaMA 7B也具备显著的语言处理能力,使我们能够高效有效地实现我们的预期结果。

官方研究论文:LLaMA: 开放且高效的基础语言模型[5]`

要在本地CPU上执行LLM,我们需要一个GGML格式的本地模型。有几种方法可以实现这一点,但最简单的方法是直接从Hugging Face模型库🤗[6]下载bin文件。在我们的情况下,我们将下载Llama 7B模型。这些模型是开源的,可供免费下载。

如果你想节省时间和精力,不用担心-我已经帮你解决了。这是你下载模型的直接链接⏬[7]。只需下载任何一个版本,然后将文件移动到我们根目录中的models目录中。这样,你就可以方便地访问模型以供使用。

GGML是什么?为什么使用GGML?如何使用GGML?LLaMA CPP是什么?

Do You Want To Know What It Is The Matrix GIFDiscover & share this Animated GIF with everyone you know. GIPHY is how you search, share, discover, and create GIFs.icon-default.png?t=N7T8https://giphy.com/gifs/reactiongifs-mrw-oc-11e0gEWxYoSYTK?utm_source=iframe&utm_medium=embed&utm_campaign=Embeds&utm_term=https%3A%2F%2Fcdn.embedly.com%2F

GGML是一个用于机器学习的张量库,它是一个允许您在仅使用CPU或CPU + GPU上运行LLM的C++库。它定义了一种用于分发大型语言模型(LLMs)的二进制格式。GGML利用一种称为量化的技术,使得大型语言模型能够在消费者硬件上运行。

那么什么是量化?

LLM的权重是浮点数(小数)。就像需要更多的空间来表示一个大整数(例如1000)比表示一个小整数(例如1)需要更多的空间一样,将浮点数的高精度(例如0.0001)与低精度浮点数(例如0.1)相比,需要更多的空间。量化一个大型语言模型的过程涉及减少权重的表示精度,以减少使用模型所需的资源。GGML支持多种不同的量化策略(例如4位、5位和8位量化),每种策略在效率和性能之间提供不同的权衡。

Llama的量化大小

为了有效使用这些模型,考虑到内存和磁盘的需求是至关重要的。由于目前模型完全加载到内存中,您需要足够的磁盘空间来存储它们,以及足够的RAM来在执行时加载它们。对于65B模型,即使经过量化处理后,建议至少有40 GB的可用RAM。值得注意的是,内存和磁盘需求目前是等价的。

量化在管理这些资源需求中起着至关重要的作用。除非您有特殊的计算资源访问🤑🤑🤑

通过减少模型参数的精度并优化内存使用,量化使得模型能够在更一般的硬件配置上运行。这确保了模型的运行能在更广泛的设备上实现可行和高效。

要在Python中使用C++库,应该如何操作?

如何在Python中使用C++库?

这就是Python绑定发挥作用的地方。绑定是指在我们的Python和C++之间创建桥梁或接口的过程。我们将使用llama-cpp-python,这是llama.cpp的Python绑定,它作为LLaMA模型在纯C/C++中的推理。llama.cpp的主要目标是使用4位整数量化运行LLaMA模型。这种集成使我们能够有效地利用LLaMA模型,充分发挥C/C++实现的优势和4位整数量化的益处🚀

llama.cpp支持的模型:源代码[8]

通过已准备好的GGML模型和我们的所有依赖项(感谢pipfile),现在是时候开始我们的LangChain之旅了。但在深入探索令人兴奋的LangChain世界之前,让我们用传统的“Hello World”仪式开始一切——毕竟,LLM也是一种语言模型 😄。

Voilà!我们已成功在CPU上执行了我们的第一个LLM,完全离线和完全随机的方式(您可以调整超参数temperature进行玩耍)。

有了这个令人激动的里程碑🎯,我们现在准备迎接我们的主要目标:使用LangChain框架进行自定义文本的问答。

第三节:开始使用LLM和LangChain整合🤝

在上一节中,我们使用llama cpp初始化了LLM。现在,让我们利用LangChain框架来开发使用LLM的应用程序。您可以通过文本与它们进行交互的主要接口是文本。简单来说,很多模型都是⬇️以文本为输入,输出文本⬆️的。因此,LangChain中的许多接口都围绕文本展开。

提示工程的兴起📈

在不断发展的编程领域中出现了一个引人注目的范例:提示。提示涉及提供特定输入给语言模型,以诱导出所期望的回应。这种创新方法使我们能够根据我们提供的输入来塑造模型的输出。

我们用提示的措辞方式的微妙差别对模型的回应性质和内容产生了显著的影响,这令人惊讶。结果可能会在语言上有根本性的不同,凸显出在构思提示时的仔细考虑的重要性。

为了为LLMs提供无缝的互动,LangChain提供了几个类和功能,以便使用提示模板轻松构建和处理提示。这是一种可复制的方法来生成提示。它包含一个文本字符串“模板”,可以接受来自最终用户的一组参数并生成一个提示。让我们看几个例子。

我希望之前的解释能更清楚地说明提示的概念。现在,让我们来提示LLM。

这个效果非常完美,但并不是LangChain的最佳利用方式。到目前为止,我们已经使用了单个组件。我们取出了提示模板进行格式化,然后取出了LLM,再将这些参数传递给LLM以生成答案。在简单的应用中,孤立使用LLM是可以的,但在更复杂的应用中,需要将LLM链接起来 - 要么彼此链接,要么与其他组件链接。

LangChain为此类链接🔗应用程序提供了Chain接口。我们通常将链定义为对组件的调用序列,其中可以包括其他链。通过链,我们可以将多个组件组合在一起,创建一个单一的、连贯的应用程序。例如,我们可以创建一个链,将用户输入与提示模板一起格式化,然后将格式化后的响应传递给LLM。通过将多个链组合在一起或将链与其他组件组合,我们还可以构建更复杂的链。

为了理解一个链,让我们创建一个非常简单的链接🔗,它将接受用户输入,使用它来格式化提示,然后使用上述已经创建的各个组件将其发送到LLM。

当处理多个变量时,您可以选择使用字典将它们集体输入。这就结束了本节内容。现在,让我们深入研究主要部分,我们将把外部文本作为问题回答目的的检索器进行整合。

第4节:生成用于问题回答的嵌入和向量存储

在许多LLM应用中,需要用户特定的数据,而这些数据不包含在模型的训练集中。LangChain为您提供了加载、转换、存储和查询数据的基本组件。

LangChain中的数据连接

五个阶段是:

1.文档加载器:用于将数据加载为文档。

2.文档转换器:将文档分割成较小的块。

3.嵌入:将块转换为矢量表示,即嵌入。

4.向量存储:用于将上述块向量存储在向量数据库中。

5.检索器:用于检索与查询中的矢量相似的一组/多组矢量,这些矢量以同一潜在空间中的嵌入形式存在。

文档检索/问答循环

现在,我们将逐步介绍执行与查询最相似的文档块检索的五个步骤。在此之后,我们可以根据检索到的向量块生成答案,如所提供的图示所示。

在继续之前,我们需要准备一个文本来执行上述任务。为了进行这个虚构的测试,我已经从维基百科上复制了一段关于一些流行的DC超级英雄的文本。以下是该文本:

加载和转换文档

首先,让我们创建一个文档对象。在这个例子中,我们将使用文本加载器。但是,语言链支持多个文档,所以根据您的具体文档,您可以使用不同的加载器。接下来,我们将使用**load**方法从预配置的来源检索数据并将其加载为文档。

一旦文档加载完毕,我们可以通过将其分成较小的块来进行转换过程。为了实现这一点,我们将使用TextSplitter。默认情况下,拆分器会在“\n\n”分隔符处将文档分开。然而,如果您将分隔符设为null并定义特定的块大小,每个块将具有指定的长度。因此,结果列表的长度将等于文档长度除以块大小。总之,它将类似于这样:列表长度 = 文档长度 / 块大小。让我们践行这番话语。

旅程的一部分就是embedding!!!

这是最重要的步骤。嵌入生成文本内容的向量化描绘。这具有实际意义,因为它允许我们在一个向量空间中概念化文本。

Word嵌入只是一个包含实数的单词的向量表示。由于语言通常包含至少数万个单词,简单的二进制词向量由于维度过高可能变得不实用。Word嵌入通过在低维向量空间中提供密集表示来解决这个问题。

当我们谈论检索时,我们是指检索与嵌入在相同潜在空间中的向量形式的查询最相似的一组向量。

LangChain中的基本嵌入类暴露了两种方法:一种用于嵌入文档,一种用于嵌入查询。前者以多个文本作为输入,而后者以单个文本作为输入。

为了全面理解嵌入,我高度推荐深入研究其基础知识,因为它们构成了神经网络处理文本数据的核心。我在其中一篇利用TensorFlow的博客中广泛涵盖了这个主题。这是链接👇

词嵌入 - 神经网络的文本表示: 嵌入是一种可以学习的自然语言表示,其中具有相似含义的单词具有相似的…[9]

创建向量存储并检索文档

向量存储有效地管理嵌入式数据的存储,并为您提供向量搜索功能。嵌入和存储嵌入向量是存储和搜索非结构化数据的普遍方法。在查询时,非结构化查询也被嵌入,检索与嵌入查询最相似的嵌入向量。这种方法能够有效地从向量存储中检索相关信息。

在这里,我们将利用Chroma,一种嵌入式数据库和向量存储,专门用于简化包含嵌入的AI应用程序的开发。它提供了一套全面的内置工具和功能,以便方便地通过执行简单的 pip install chromadb 命令在本地机器上安装。

到目前为止,我们已经见证了嵌入和向量存储在从大量文件集合中检索相关片段方面的显著能力。现在,是时候将这个检索到的片段作为上下文与我们的查询一起呈现给LLM了。用它神奇的魔杖一挥,我们将恳求LLM基于我们提供的信息生成答案。重要的部分是提示结构。

然而,强调一个良好结构的提示的重要性是至关重要的。通过制定一个精心设计的提示,我们可以减轻LLM在面对不确定性时可能发生的幻觉,即它可能会编造事实。

不再拖延等待时间,我们现在继续进行最后阶段,并发现我们的LLM是否能够产生一个引人入胜的答案。时机已经到来,我们要见证我们努力的顶点,揭示结果。我们去吧 ⚡

(与医生的问答)

这就是我们一直等待的时刻!我们做到了!👏👏我们刚刚构建了我们自己的问题回答机器人🤖,利用本地运行的LLM。⚡⚡

第五部分:使用Streamlit🔥链接所有内容

本节完全可选,因为它不是Streamlit的全面指南。我不会深入研究这部分内容,而是提供一个基本应用程序,允许用户上传任何文本文档。然后,他们将有机会通过文本输入来提出问题。在幕后,功能将与我们在前一节中涵盖的内容保持一致。

然而,在Streamlit中上传文件有一个注意事项。为了防止潜在的内存错误,特别是考虑到LLMs的内存密集型特性,我将简单地读取文档并将其写入我们文件结构中的临时文件夹中,命名为raw.txt。这样,无论文档的原始名称是什么,Textloader都将在将来无缝处理它。

目前,该应用程序设计用于文本文件,但您可以将其适应为PDF、CSV或其他格式。基本概念保持不变,因为LLMs主要设计用于文本输入和输出。此外,您可以尝试使用Llama C++绑定支持的不同LLMs。

不深入研究复杂的细节,我提供这个应用的代码。请随意根据您特定的使用情况进行自定义。

# Bring in deps
import streamlit as st 
from langchain.llms import LlamaCpp
from langchain.embeddings import LlamaCppEmbeddings
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from langchain.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import Chroma


# Customize the layout
st.set_page_config(page_title="DOCAI", page_icon="🤖", layout="wide", )     
st.markdown(f"""
            <style>
            .stApp {{background-image: url("https://images.unsplash.com/photo-1509537257950-20f875b03669?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1469&q=80"); 
                     background-attachment: fixed;
                     background-size: cover}}
         </style>
         """, unsafe_allow_html=True)

# function for writing uploaded file in temp
def write_text_file(content, file_path):
    try:
        with open(file_path, 'w') as file:
            file.write(content)
        return True
    except Exception as e:
        print(f"Error occurred while writing the file: {e}")
        return False

# set prompt template
prompt_template = """Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer.
{context}
Question: {question}
Answer:"""
prompt = PromptTemplate(template=prompt_template, input_variables=["context", "question"])

# initialize hte LLM & Embeddings
llm = LlamaCpp(model_path="./models/llama-7b.ggmlv3.q4_0.bin")
embeddings = LlamaCppEmbeddings(model_path="models/llama-7b.ggmlv3.q4_0.bin")
llm_chain = LLMChain(llm=llm, prompt=prompt)

st.title("📄 Document Conversation 🤖")
uploaded_file = st.file_uploader("Upload an article", type="txt")

if uploaded_file is not None:
    content = uploaded_file.read().decode('utf-8')
    # st.write(content)
    file_path = "temp/file.txt"
    write_text_file(content, file_path)   
    
    loader = TextLoader(file_path)
    docs = loader.load()    
    text_splitter = CharacterTextSplitter(chunk_size=100, chunk_overlap=0)
    texts = text_splitter.split_documents(docs)
    db = Chroma.from_documents(texts, embeddings)    
    st.success("File Loaded Successfully!!")
    
    # Query through LLM    
    question = st.text_input("Ask something from the file", placeholder="Find something similar to: ....this.... in the text?", disabled=not uploaded_file,)    
    if question:
        similar_doc = db.similarity_search(question, k=1)
        context = similar_doc[0].page_content
        query_llm = LLMChain(llm=llm, prompt=prompt)
        response = query_llm.run({"context": context, "question": question})        
        st.write(response)

以下是streamlit应用程序的样子🔥。

这次我提供了从维基中复制的《蝙蝠侠:黑暗骑士》的情节,并询问“谁的脸被严重烧伤了?”然后LLM回答说——“哈维·登特”。

好了,好了,好了!就这样,我们完成了这篇博客。

我希望您喜欢这篇文章!并且觉得它有用且有趣。您可以通过Afaque Umer[10]来关注我,了解更多类似的文章。

我将努力提出更多机器学习/数据科学概念,并尝试将那些听起来高级的术语和概念解释得更简单。

我是查老师,我们下期见!!!

声明

本文原作者为査老师,

翻译整理出自:https://ai.plainenglish.io/%EF%B8%8F-langchain-streamlit-llama-bringing-conversational-ai-to-your-local-machine-a1736252b172

持续更新更多的AI相关的内容,感兴趣的请点赞、关注、收藏。

References

[1] 《大型语言模型综述》: https://arxiv.org/abs/2303.18223
[2] 官方文档https://python.langchain.com/docs/get_started/introduction.html
[3] GitHub - afaqueumer/DocQA: Question Answering with Custom FIles using LLMs: https://github.com/afaqueumer/DocQA
[4] LLaMA: https://research.facebook.com/publications/llama-open-and-efficient-foundation-language-models/
[5] LLaMA: 开放且高效的基础语言模型: https://research.facebook.com/publications/llama-open-and-efficient-foundation-language-models/
[6] Hugging Face模型库🤗: https://huggingface.co/models
[7] 下载地址: https://huggingface.co/TheBloke/LLaMa-7B-GGML
[8] 源代码https://github.com/ggerganov/llama.cpp
[9] 词嵌入 - 神经网络的文本表示: 嵌入是一种可以学习的自然语言表示,其中具有相似含义的单词具有相似的…: https://medium.com/codex/word-embeddings-text-representation-for-neural-networks-65fd934d1fa2
[10] Afaque Umer: https://medium.com/u/430bc504f9d9

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

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

相关文章

云计算学习——5G网络技术

系列文章目录 提示&#xff1a;仅用于个人学习&#xff0c;进行查漏补缺使用。 Day1 网络参考模型 Day2 网络综合布线与应用 Day3 IP地址 Day4 华为eNSP网络设备模拟器的基础安装及简单使用 Day5 交换机的基本原理与配置 Day6 路由器的原理与配置 Day7 网络层协议介绍一 Day8 …

【Pyhton】数据类型之详讲字符串(上)

本篇文章将详细讲解字符串&#xff1a; 1、定义 定义字符串时&#xff0c;字符串的内容被双引号&#xff0c;单引号&#xff0c;三单引号&#xff0c;三双引号中的其中一个被括住。 例如&#xff1a; 双引号&#xff1a; v1"haha" 单引号&#xff1a; v1hahah…

数据结构-1.初始包装类与泛型

本节目标:学习包装类与泛型为阅读java集合源码打下基础. 1.包装类 在 Java 中&#xff0c;由于基本类型不是继承自 Object &#xff0c;为了在泛型代码中可以支持基本类型&#xff0c; Java 给每个基本类型都对应了一个包装类型. 1.1基本数据类型对应包装类 基本数据类型包装类…

编码的理解

人类的文字信息由各种各样的符号构成 文字-----符号 这些符号是不能在磁盘或内存当中存储的&#xff0c;计算机最早是由老美发明出来的&#xff0c;内存和磁盘当中只有 0&#xff0c;1&#xff0c;严格来说内存和磁盘中只能表示整型&#xff0c;那么我们应该怎么表示符号----…

linux进程控制——进程替换——exec函数接口

前言&#xff1a; 本节内容进入linux进程控制板块的最后一个知识点——进程替换。 通过本板块的学习&#xff0c; 我们了解了进程的基本控制方法——进程创建&#xff0c; 进程退出&#xff0c; 进程终止&#xff0c; 进程替换。 进程控制章节和上一节进程概念板块都是在谈进程…

智算新风向丨趋动科技获中国信通院泰尔实验室首张智算资源池化能力泰尔测评证书

近日&#xff0c;趋动科技“OrionX AI算力资源池化软件”经中国泰尔实验室依据《FG-Z14-0172-01智算资源池化平台测试方案》评估测试&#xff0c;获得智算资源池化能力泰尔测评证书&#xff0c;成为该领域首个完成此评价的产品。 图1.OrionX通过智算资源池化平台评测 随着AI大…

智能巡检企业级域名 SSL 证书

一、概述 SSL 证书是一种数字证书&#xff0c;用于在用户和服务器之间建立加密链接&#xff0c;确保数据传输的安全性&#xff0c;防止数据在传输过程中被截获或篡改。SSL 证书不仅保护了数据传输过程中的隐私和完整性&#xff0c;还可以帮助验证网站的身份&#xff0c;防止钓…

基于SpringBoot+Vue的科研管理系统(带1w+文档)

基于SpringBootVue的科研管理系统(带1w文档) 基于SpringBootVue的科研管理系统(带1w文档) 科研的管理系统设计过程中采用Java开发语言,B/S结构&#xff0c;采取springboot框架&#xff0c;并以MySql为数据库进行开发。结合以上技术&#xff0c;对本系统的整体、数据库、功能模块…

鸿蒙系统开发【加解密算法库框架】安全

加解密算法库框架 介绍 本示例使用ohos.security.cryptoFramework相关接口实现了对文本文件的加解密、签名验签操作。 实现场景如下&#xff1a; 1&#xff09;软件需要加密存储本地文本文件&#xff0c;需要调用加解密算法库框架选择密钥文本文件&#xff0c;对本地文本文…

PostgreSQL11 | 触发器

本文章代码已在pgsql11.22版本上运行且通过&#xff0c;展示页由pgAdmin8.4版本提供 上一篇总结了原著的第十章有关pgsql的视图的用法&#xff0c;本篇将总结pgsql的触发器的用法。 触发器 使用触发器可以自动化完成一些在插入数据或修改数据时&#xff0c;某些需要同期同步的…

【vulnhub】Depth靶机

靶机安装 下载地址&#xff1a;https://download.vulnhub.com/depth/DepthB2R.ova 运行环境&#xff1a;VMware运行该虚拟机 信息收集 靶机IP发现 nmap 192.168.93.0/24 端口扫描 nmap -A 192.168.93.154 -p- 只开起了8080端口 进行目录扫描8080端口 dirsearch -u http…

学习记录(9):Prompt提示词技巧

依旧照例先感谢前辈们的慷慨分享 今天学习的是这篇文章↓ 原文&#xff1a;转自公主号“博金斯的AI笔记” —《4篇Prompt论文的提示词技巧, 3 个 GPTs 实例测试》 文章目录 一、提示词框架二、逻辑链&#xff08;Chain of thought&#xff09;三、思维树&#xff08;Tree of th…

华为Atlas 500 智能小站+鸿蒙AI大算力边缘计算解决方案

Atlas 500 智能小站鸿蒙大算力解决方案 技术规格 表3-1 技术规格 项目 说明 处理器 海思Hi3559A处理器 双核ARM Cortex A731.6GHz&#xff0c;32KB I-Cache&#xff0c;64KB D-Cache /512KB L2 cache双核ARM Cortex A531.2GHz&#xff0c;32KB I-Cache&#xff0c;32KB D-C…

如何确保PLC系统安全的可靠性,这几个注意事项你需要牢记

PLC&#xff08;可编程逻辑控制器&#xff09;是现代工业自动化系统中的关键组成部分。在设计 PLC 系统时&#xff0c;安全性是至关重要的考虑因素。本文将介绍 PLC 系统设计中的一些安全注意事项&#xff0c;包括电源设计、接地设计、关键数字量输入输出设计和报警设计。 一.…

阿一网络安全学院之绕过CDN发现服务器真实IP

方法一&#xff1a; 探测次级域名 方法二&#xff1a; 访问文件 使用访问错误目录获得报错信息成功 方法三&#xff1a; 去掉 www 查询 方法四&#xff1a; 使用网络测绘搜索引擎查询 和方法二获得的 IP 一样 方法五&#xff1a; 使用外国节点查询&#xff1a; 用了无数…

关于使用php的mpdf插件遇到的一些问题

一.插件版本 "mpdf/mpdf": "^8.0", 二.报错&#xff1a;Undefined index: list_style_type 这个是插件无法识别 li 标签导致&#xff0c;生成pdf是加入下面代码 <style> li { list-style-type: none; list-style-image: none; list-style-positi…

HTML-03.新浪新闻-标题-样式2

1.<span>标签 <span>是一个在开发网页时大量使用的没有语义的布局标签 特点&#xff1a;一行可以显示多个&#xff08;行内组合元素&#xff09;&#xff0c;宽度和高度默认由内容撑开 2.CSS选择器 2.1 元素选择器&#xff1a;标签名{...} 元素名称{ color:red; }…

如何在 Debian 上安装运行极狐GitLab Runner?【一】

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门面向中国程序员和企业提供企业级一体化 DevOps 平台&#xff0c;用来帮助用户实现需求管理、源代码托管、CI/CD、安全合规&#xff0c;而且所有的操作都是在一个平台上进行&#xff0c;省事省心省钱。可以一键安装极狐GitL…

04-Fastjson反序列化漏洞

免责声明 本文仅限于学习讨论与技术知识的分享&#xff0c;不得违反当地国家的法律法规。对于传播、利用文章中提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;本文作者不为此承担任何责任&#xff0c;一旦造成后果请自行承担&…

ShardingSphere实战(5)- 读写分离

上篇博客&#xff0c;我们讲了 ShardingSphere实战&#xff08;4&#xff09;- 广播表和默认数据源 &#xff0c;这篇博客&#xff0c;我们实现一下读写分离。 一、读写分离配置 # sharding-jdbc 读写分离策略 # 给数据源起别名&#xff0c;这里名称需要和下面的一致 spring.…