LLM-文本分块(langchain)与向量化(阿里云DashVector)存储,嵌入LLM实践

文章目录

  • 前言
  • 向量、令牌、嵌入
  • 分块
    • 按字符拆分
    • 按字符递归拆分
    • 按token拆分
  • 向量化
  • 使用 TextEmbedding 实现语义搜索
    • 数据准备
    • 通过 DashScope 生成 Embedding 向量
    • 通过 DashVector 构建检索:向量入库
    • 语义检索:向量查询
    • 完整代码
  • 总结

前言

Transformer 架构已经成为当今深度学习的趋势,大家一定也经常听到 token, 向量化嵌入等名词概念,可以说这三个是 Transformer 架构实现自注意力的关键,限于本文主题,下边会简单介绍下这三个概念,以及之间的关系,但不会详细多说,网上已经有很多比较好的文章进行了说明总结。

现在有很多开源的库可以对文本进行分块,比如说 langchaintext_splitter包,以及许多优秀的开源向量数据库,比如说Chroma,Milvus,Weaviate等,虽然我们可以使用这些开源的工具进行分块和向量化存储,但是我一直认为上云,使用云服务才是大势所趋(将这些中间件服务交给云服务商可以大大减少公司的运维费用)。

本文首先会对阿里云的向量检索服务DashVector进行简单使用说明,然后会结合灵积模型服务上的Embedding API,来从0到1构建基于文本索引的构建+向量检索基础上的语义搜索能力。具体来说,我们将基于QQ 浏览器搜索标题语料库(QBQTC:QQ Browser Query Title Corpus)进行实时的文本语义搜索,查询最相似的相关标题。

前提条件:

  • 开通灵积模型服务,并获得 API-KEY:开通DashScope并创建API-KEY。
  • 开通DashVector向量检索服务,并获得 API-KEYAPI-KEY管理。
  • 已创建向量检索服务Cluster:创建Cluster。
  • 已获得向量检索服务API-KEY:API-KEY管理。
  • 已安装最新版SDK:安装DashVector SDK。

向量、令牌、嵌入

向量 (Vectors)

  • 向量在LLM中扮演了基石的角色,通过将文本数据转换成高维向量空间中的表示,使机器能够理解语言。这种转换后的向量称为“语义向量嵌入”,能够编码和体现文本的实际语义信息。
  • 与传统离散符号表示相比,语义向量嵌入能够自动捕捉并编码单词间的同义关系、语法关联及上下文语义信息,使得语义相似的词语在向量空间中彼此接近。
  • 这种连续的向量表示简化了数据结构的复杂度,为神经网络模型提供了紧凑且信息丰富的内部数据形式,显著提升了模型的学习和表现能力。

令牌 (Tokens)

  • 令牌是文本数据在LLM内部的表示形式,可以是单词、子词或字符,具体取决于令牌化策略。
  • 令牌化是将原始文本转换为模型可解释的离散符号序列的过程,这一过程对模型的输入表示和计算效率产生直接影响。
  • 合理的令牌化策略不仅能减少词汇表大小,解决未知词问题,还能为模型提供更好的语义信号,提高其泛化能力。不同LLM会采用不同的令牌化方案以最大化发挥模型潜力。

嵌入 (Embeddings)

  • 嵌入是赋予令牌以语义语境的关键环节,代表了文本的意义和上下文信息。它是一种融入了语境的令牌表征,由嵌入模型生成,以向量形式存在,捕捉了令牌之间的语义关联和上下文依赖。
  • 嵌入不仅编码了令牌的身份,更重要的是捕捉了令牌间的关系,使得LLM能够理解语境、微妙语义和词语/短语的细微差异。高质量的嵌入使得LLM在各类自然语言处理任务中展现出人类甚至超人类水平的能力。

三者关系

  • 令牌、向量和嵌入在LLM的处理流程中紧密相关又各具特色。令牌是语言的最小单元,每个令牌在模型底层表现为向量,便于机器计算。
  • 向量为令牌提供了数学框架,但仅凭向量难以准确反映语义信息,此时嵌入技术显得尤为重要。
  • 嵌入是经过专门训练的向量表示,能够体现词语/短语间的相似性、类比关系等丰富语义,为LLM提供更细腻的语义理解基础。
  • 令牌化将文本转换为离散标记,而嵌入则将这些标记映射到语义向量空间,赋予上下文语境,实现了从离散语言符号到连续语义空间的转变。

分块

pip install langchain

按字符拆分

# 读取需要拆分的文本内容
with open("../../splitters_test.txt") as f:state_of_the_union = f.read()from langchain_text_splitters import CharacterTextSplittertext_splitter = CharacterTextSplitter(separator="\n\n",chunk_size=1000,chunk_overlap=200,length_function=len,is_separator_regex=False,
)texts = text_splitter.create_documents([state_of_the_union])
print(texts[0])
  • separators - 分隔符字符串数组
  • chunk_size - 每个文档的字符数量限制
  • chunk_overlap - 两份文档重叠区域的长度
  • length_function - 长度计算函数
  • is_separator_regex - 如果为真:应当被解释为正则表达式,因此不需要转义。如果为假:应当被当作普通字符串分隔符,并转义任何特殊字符。

将元数据与文档一起传递:

meta_datas = [{"document": 1}, {"document": 2}]
documents = text_splitter.create_documents([state_of_the_union, state_of_the_union], metadatas=meta_datas
)
print(len(documents))
print(documents[0])
print(documents[3])

按字符递归拆分

对于通用文本,建议使用此文本拆分器。它由字符列表参数化。它试图按顺序分割它们,直到这些块足够小。默认列表是 [“\n\n”, “\n”, " ", “”] 。这样做的效果是尽量将所有段落(然后是句子,然后是单词)保持在一起,因为这些段落一般看起来是语义最相关的文本片段。

from langchain_text_splitters import RecursiveCharacterTextSplitter# This is a long document we can split up.
with open("./demo_static/splitters_test.txt") as f:state_of_the_union = f.read()text_splitter = RecursiveCharacterTextSplitter(# Set a really small chunk size, just to show.chunk_size=100,chunk_overlap=20,length_function=len,is_separator_regex=False,
)texts = text_splitter.create_documents([state_of_the_union])
print(texts[0])
print(texts[1])

从没有单词边界的语言中拆分文本

一些书写系统没有单词边界,例如 中文 、日文和泰文。使用默认分隔符列表拆分文本[“\n\n”, “\n”, " ", “”]会导致单词在单词块之间拆分。

text_splitter = RecursiveCharacterTextSplitter(separators=["\n\n","\n"," ",".",",","\u200B",  # Zero-width space"\uff0c",  # Fullwidth comma"\u3001",  # Ideographic comma"\uff0e",  # Fullwidth full stop"\u3002",  # Ideographic full stop"",],# Existing args
)

按token拆分

使用 tiktoken

pip install --upgrade --quiet langchain-text-splitters tiktoken

from langchain_text_splitters import CharacterTextSplitter
# This is a long document we can split up.
with open("./demo_static/splitters_test.txt") as f:state_of_the_union = f.read()text_splitter = CharacterTextSplitter.from_tiktoken_encoder(model_name="gpt-4", chunk_size=100, chunk_overlap=0
)
texts = text_splitter.split_text(state_of_the_union)

使用 spacy
pip install --upgrade --quiet spacy

from langchain_text_splitters import SpacyTextSplitter
# This is a long document we can split up.
with open("./demo_static/splitters_test.txt") as f:state_of_the_union = f.read()text_splitter = SpacyTextSplitter(chunk_size=1000)texts = text_splitter.split_text(state_of_the_union)
print(texts[0])

使用 SentenceTransformers

from langchain_text_splitters import SentenceTransformersTokenTextSplittersplitter = SentenceTransformersTokenTextSplitter(chunk_overlap=0)
text = "Lorem "count_start_and_stop_tokens = 2
text_token_count = splitter.count_tokens(text=text) - count_start_and_stop_tokens
print(text_token_count)token_multiplier = splitter.maximum_tokens_per_chunk // text_token_count + 1# `text_to_split` does not fit in a single chunk
text_to_split = text * token_multiplierprint(f"tokens in text to split: {splitter.count_tokens(text=text_to_split)}")text_chunks = splitter.split_text(text=text_to_split)print(text_chunks[1])

使用 NLTK
pip install nltk

from langchain_text_splitters import NLTKTextSplitter# This is a long document we can split up.
with open("./demo_static/splitters_test.txt") as f:state_of_the_union = f.read()text_splitter = NLTKTextSplitter(chunk_size=1000)texts = text_splitter.split_text(state_of_the_union)
print(texts[0])

向量化

这里使用阿里云的 DashVector云服务进行向量化操作,包括存储与检索,首先需要确定我们已经开通了上边的前提条件。(现在可以免费开通试用一个月),向量检索服务官方文档。

pip install dashvector

创建 Client
YOUR_API_KEY 和 YOUR_CLUSTER_ENDPOINT 可以在向量检索服务控制台查看 。

import dashvectorclient = dashvector.Client(api_key='YOUR_API_KEY',endpoint='YOUR_CLUSTER_ENDPOINT'
)
assert client

创建Collection
创建一个名称为quickstart,向量维度为4的collection。

client.create(name='quickstart', dimension=4)collection = client.get('quickstart')
assert collection

插入Doc

from dashvector import Doc# 通过dashvector.Doc对象,插入单条数据
collection.insert(Doc(id='1', vector=[0.1, 0.2, 0.3, 0.4]))# 通过dashvector.Doc对象,批量插入2条数据
collection.insert([Doc(id='2', vector=[0.2, 0.3, 0.4, 0.5], fields={'age': 20, 'name': 'zhangsan'}),Doc(id='3', vector=[0.3, 0.4, 0.5, 0.6], fields={'anykey': 'anyvalue'})    ]
)
  • 这里的fields是为了增加检索准确性,可以在检索的时候加上一些过滤条件等,具体的可以参考文档。
  • 插入成功后可以在向量检索服务控制台看到我们插入的向量数据:
    image.png

相似性检索

rets = collection.query([0.1, 0.2, 0.3, 0.4], topk=2)print(rets)# 输出如下
{"code": 0, "message": "Success", "requests_id": "24731ff6-d3b4-475a-9309-d66428b684bc", "output": [{"id": "1", "fields": {}, "score": 0.0}, {"id": "2", "fields": {"age": 20, "name": "zhangsan"}, "score": 0.0062}]}

删除Doc

# 删除1条数据
collection.delete(ids=['1'])

查看Collection统计信息

stats = collection.stats()print(stats)

删除Collection

client.delete('quickstart')

上边都是对简单的 CRUD 操作,还有一些比较高级的使用,比如说使用 Field 字段过滤,增加检索准确性,使用 分区 Partition,向量动态量化等,官方文档都写的很清晰,这里只起一个抛砖引玉的作用,如果要在生产环境中使用,还是得全面了解下官方文档。

使用 TextEmbedding 实现语义搜索

接下来我们利用 DashVector 和 Embedding API 构建一个实时的索引服务和查询。
具体的架构图如下:
image.png
环境安装
pip3 install dashvector dashscope

数据准备

git clone https://github.com/CLUEbenchmark/QBQTC.git
wc -l QBQTC/dataset/train.json

数据集中的训练集(train.json)其格式为 json:

{"id": 0, "query": "小孩咳嗽感冒", "title": "小孩感冒过后久咳嗽该吃什么药育儿问答宝宝树", "label": "1"
}

我们将从这个数据集中提取title,方便后续进行embedding并构建检索服务。

import jsondef prepare_data(path, size):with open(path, 'r', encoding='utf-8') as f:batch_docs = []for line in f:batch_docs.append(json.loads(line.strip()))if len(batch_docs) == size:yield batch_docs[:]batch_docs.clear()if batch_docs:yield batch_docs

通过 DashScope 生成 Embedding 向量

import dashscope
from dashscope import TextEmbedding# 需要使用自己的api-key替换示例中的 your-dashscope-api-key 
dashscope.api_key='{your-dashscope-api-key}'def generate_embeddings(text):rsp = TextEmbedding.call(model=TextEmbedding.Models.text_embedding_v1,input=text)embeddings = [record['embedding'] for record in rsp.output['embeddings']]return embeddings if isinstance(text, list) else embeddings[0]# 查看下embedding向量的维数,后面使用 DashVector 检索服务时会用到,目前是1536
print(len(generate_embeddings('hello')))
  • 需要使用自己的api-key替换示例中的 your-dashscope-api-key

通过 DashVector 构建检索:向量入库

DashVector 向量检索服务上的数据以集合(Collection)为单位存储,写入向量之前,我们首先需要先创建一个集合来管理数据集。创建集合的时候,需要指定向量维度,这里的每一个输入文本经过DashScope上的text_embedding_v1模型产生的向量,维度统一均为1536。

DashVector 除了提供向量检索服务外,还提供倒排过滤功能 和 scheme free 功能。所以我们为了演示方便,可以写入数据时,可以将title内容写入 DashVector 以便召回。写入数据还需要指定 id,我们可以直接使用 QBQTC 中id。

from dashvector import Client, Doc# 初始化 DashVector client
client = Client(api_key='{your-dashvector-api-key}',endpoint='{your-dashvector-cluster-endpoint}'
)# 指定集合名称和向量维度
rsp = client.create('sample', 1536)
assert rspcollection = client.get('sample')
assert collectionbatch_size = 10
for docs in list(prepare_data('QBQTC/dataset/train.json', batch_size)):# 批量 embeddingembeddings = generate_embeddings([doc['title'] for doc in docs])# 批量写入数据rsp = collection.insert([Doc(id=str(doc['id']), vector=embedding, fields={"title": doc['title']}) for doc, embedding in zip(docs, embeddings)])assert rsp

语义检索:向量查询

在把QBQTC训练数据集里的title内容都写到DashVector服务上的集合里后,就可以进行快速的向量检索,实现“语义搜索”的能力。继续上面代码的例子,假如我们要搜索有多少和’应届生 招聘’相关的title内容,可以通过在DashVector上去查询’应届生 招聘’,即可迅速获取与该查询语义相近的内容,以及对应内容与输入之间的相似指数。

# 基于向量检索的语义搜索
rsp = collection.query(generate_embeddings('应届生 招聘'), output_fields=['title'])for doc in rsp.output:print(f"id: {doc.id}, title: {doc.fields['title']}, score: {doc.score}")

完整代码

import jsonimport dashscope
from dashscope import TextEmbedding
from dashvector import Client, Docdef prepare_data(path, size):with open(path, 'r', encoding='utf-8') as f:batch_docs = []for line in f:batch_docs.append(json.loads(line.strip()))if len(batch_docs) == size:yield batch_docs[:]batch_docs.clear()if batch_docs:yield batch_docsdef init_vector_collections(api_key, endpoint):client = Client(api_key=api_key,endpoint=endpoint)# 指定集合名称和向量维度client.create('sample', 1536)collection = client.get('sample')return collectiondef generate_embeddings(text):rsp = TextEmbedding.call(model=TextEmbedding.Models.text_embedding_v1,input=text)embeddings = [record['embedding'] for record in rsp.output['embeddings']]return embeddings if isinstance(text, list) else embeddings[0]# 查看下embedding向量的维数,后面使用 DashVector 检索服务时会用到,目前是1536
# print(len(generate_embeddings('hello')))def write_embeddings(path, collection):batch_size = 10for docs in list(prepare_data(path, batch_size)):# 批量 embeddingembeddings = generate_embeddings([doc['title'] for doc in docs])# 批量写入数据rsp = collection.insert([Doc(id=str(doc['id']), vector=embedding, fields={"title": doc['title']})for doc, embedding in zip(docs, embeddings)])assert rspdef query(query_str, output_field, collection):# 基于向量检索的语义搜索rsp = collection.query(generate_embeddings(query_str), output_fields=[output_field])for doc in rsp.output:print(f"id: {doc.id}, title: {doc.fields['title']}, score: {doc.score}")if __name__ == '__main__':# 下边的 api key 和 endpoint 需要替换为自己的dashscope.api_key = ''vector_api_key = ''vector_endpoint = ''path = 'train.json'collection = init_vector_collections(vector_api_key, vector_endpoint)# write_embeddings(path, collection)query('应届生 招聘', 'title', collection)

查询结果如下:

id: 301, title: 2015四大之路给自己最完美的交代-普华永道pwc2021校园招聘-应届生求职招聘论坛, score: 0.5732
id: 285, title: 关于实习生考研请假的实施意见试行-河南省中医院, score: 0.5834
id: 427, title: 2013年高考就业率高的专业建筑学专业高考热门专业专业解读中国教育在线, score: 0.6353
id: 295, title: 太原理工大学研究生院, score: 0.6492
id: 134, title: 昆山人才网昆山人力资源网-昆山人才网昆山政府旗下唯一官方招聘网昆山人才市场昆山人力资源市场主办, score: 0.6622
id: 202, title: 国家公务员报考条件-搜狗百科, score: 0.6672
id: 435, title: 西南财经大学继续网络教育学院门户网站, score: 0.6685
id: 52, title: 20141月教师要涨工资了峡山区吧百度贴吧, score: 0.6891
id: 193, title: directsalesjobsinhongkong-sep2020jobsdb, score: 0.7003
id: 280, title: 机场副总经理竞聘报告副总经理竞聘述职竞聘稿副总经理兼总经济师竞聘-fanwenqcn, score: 0.7054

总结

如何将数据分块,然后向量化嵌入向量数据库中,是 LLM 能够成功预测下一个 token 的关键,本文简单介绍了阿里云向量数据库 DashVector 的使用,并且使用一个具体的案例,将整个流程给串起来,关于 DashVector 还有很多高级功能这里并没有使用,读者可以 自行探索使用以下。

后续我会结合阿里云的通义千问大模型和 DashVector 打造一个专业的知识库,以及如何使用多模态嵌入和大模型交互的场景实战。

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

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

相关文章

[C++][ProtoBuf][Proto3语法][三]详细讲解

目录 1.默认值2.更新消息1.更新规则2.保留字段reserved 3.未知字段1.是什么?2.未知字段从哪获取 4.前后兼容性5.选项option1.选项分类2.常用选项列举3.设置自定义选项 1.默认值 反序列化消息时,如果被反序列化的⼆进制序列中不包含某个字段,…

基于Spring Boot的旅游信息推荐信息系统设计与实现(源码+lw+部署+讲解)

技术指标 开发语言:Java 框架:Spring BootJSP JDK版本:JDK1.8 数据库:MySQL5.7 数据库工具:Navicat16 开发软件:IDEA Maven包:Maven3.6.3 浏览器:IE浏览器 功能描述 旅游信…

Hadoop-19 Flume Agent批量采集数据到HDFS集群 监听Hive的日志 操作则把记录写入到HDFS 方便后续分析

章节内容 上一节我们完成了内容: Flume 启动测试Flume Conf编写Flume 测试发送和接收数据 背景介绍 这里是三台公网云服务器,每台 2C4G,搭建一个Hadoop的学习环境,供我学习。 之前已经在 VM 虚拟机上搭建过一次,但…

深入探索大语言模型

深入探索大语言模型 引言 大语言模型(LLM)是现代人工智能领域中最为重要的突破之一。这些模型在自然语言处理(NLP)任务中展示了惊人的能力,从文本生成到问答系统,无所不包。本文将从多个角度全面介绍大语…

AGE agtype 简介

AGE 使用一种名为 agtype 的自定义数据类型,这是 AGE 返回的唯一数据类型。agtype 是 Json 的超集,也是 JsonB 的自定义实现。 简单数据类型 Null 在Cypher中,null用于表示缺失或未定义的值。概念上,null表示“缺失的未知值”&…

路径规划 | 基于蚁群算法的三维无人机航迹规划(Matlab)

目录 效果一览基本介绍程序设计参考文献 效果一览 基本介绍 基于蚁群算法的三维无人机航迹规划(Matlab)。 蚁群算法(Ant Colony Optimization,ACO)是一种模拟蚂蚁觅食行为的启发式算法。该算法通过模拟蚂蚁在寻找食物时…

【安全设备】Web应用防火墙

一、什么是Web应用防火墙 Web应用程序防火墙(Web Application Firewall)的缩写是WAF,用于保护Web应用程序免受各种恶意攻击和漏洞利用。WAF通过监控和过滤进出Web应用程序的HTTP/HTTPS流量来工作。它位于Web应用程序和用户之间,分…

【总线】AXI第九课时:介绍AXI响应信号 (Response Signaling):RRESP和 BRESP

大家好,欢迎来到今天的总线学习时间!如果你对电子设计、特别是FPGA和SoC设计感兴趣,那你绝对不能错过我们今天的主角——AXI4总线。作为ARM公司AMBA总线家族中的佼佼者,AXI4以其高性能和高度可扩展性,成为了现代电子系统中不可或缺的通信桥梁…

STM32F103RB多通道ADC转换功能实现(DMA)

目录 概述 1 硬件 1.1 硬件实物介绍 1.2 nucleo-f103rb 1.3 软件版本 2 软件实现 2.1 STM32Cube配置参数 2.2 项目代码 3 功能代码实现 3.1 ADC功能函数 3.2 函数调用 4 测试 4.1 DMA配置data width:byte 4.2 DMA配置data width:Half wor…

java如何实现一个死锁 ?

死锁(Deadlock)是指在并发系统中,两个或多个线程(或进程)因争夺资源而互相等待,导致它们都无法继续执行的一种状态。 一、简易代码 public class DeadlockExample {private static final Object lock1 = new Object();private

如何在 ASP.NET MVC 项目中使用身份验证器应用程序实现多因素身份验证?

介绍 增强安全性对于任何应用程序都至关重要,而多因素身份验证 (MFA) 是实现此目标的有效方法。在本文中,我们将介绍在 ASP.NET MVC 项目中使用身份验证器应用程序集成 MFA 的过程。无论您是从头开始还是将 MFA 添加到现有项目,本指南都将提…

生物素标记降钙素Biotin-α-CGRP, rat 中间体

生物素标记降钙素Biotin-α-CGRP, rat 中间体是一种特定的生物化学试剂,主要用于科学研究领域。以下是对该产品的详细介绍: 一、基本信息 产品名称:生物素标记降钙素Biotin-α-CGRP, rat 中间体 英文名称:Biotin-α-CGRP, rat 纯度…

Qt 线程同步机制 互斥锁 信号量 条件变量 读写锁

qt线程同步 Qt提供了丰富的线程同步机制来帮助开发者更高效和安全地进行多线程编程。其主要包括: QMutex:为共享数据提供互斥访问能力,避免同时写入导致的数据冲突。利用lock()/unlock()方法实现锁定和解锁。 QReadWriteLock:读写锁,允许多个读线程同时访问,但写操作需要独占…

springboot社区物资交易互助平台+lw+源码+调试+讲解

第3章 系统分析 用户的需求以及与本系统相似的在市场上存在的其它系统可以作为系统分析中参考的资料,分析人员可以根据这些信息确定出本系统具备的功能,分析出本系统具备的性能等内容。 3.1可行性分析 尽管系统是根据用户的要求进行制作,但…

windows USB 设备驱动开发-USB带宽

本文讨论如何仔细管理 USB 带宽的指导。 每个 USB 客户端驱动程序都有责任最大程度地减少其使用的 USB 带宽,并尽快将未使用的带宽返回到可用带宽池。 在这里,我们认为USB 2.0 的速度是480Mbps、12Mbps、1.5Mbps,这分别对应高速、全速、低速…

Python面试宝典第9题:买卖股票

题目 给定一个整型数组,它的第i个元素是一支给定股票第i天的价格。如果最多只允许完成一笔交易(即买入和卖出一支股票一次),设计一个算法来计算你所能获取的最大利润。注意:你不能在买入股票前卖出股票。 示例 1&#…

LabVIEW平台从离散光子到连续光子的光子计数技术

光子计数技术用于将输入光子数转换为离散脉冲。常见的光子计数器假设光子是离散到达的,记录到来的每一个光子。但是,当两个或多个光子同时到达时,计数器会将其记录为单个脉冲,从而只计数一次。当连续光子到达时,离散光…

python学习-容器类型

列表 列表(list)是一种有序容器,可以向其中添加或删除任意元素. 列表数据类型是一种容器类型,列表中可以存放不同数据类型的值,代码示例如下: 列表中可以实现元素的增、删、改、查。 示例代码如下: 增 …

基于Unity3D的Rokid AR Glass项目开发环境搭建

初识Rokid AR 一、SDK简介二、准备工作1.软件环境2.硬件环境 三、快速接入SDK1.配置Package Manager2.安装UXR2.0 SDK 四、导入官方Demo进行模拟器测试五、Rokid AR系列教程 一、SDK简介 UXR2.0 SDK是Rokid为Unity开发者提供的AR开发工具包,提供空间定位跟踪、双目…

Windows 网络重置及重置网络可能出现的问题( WIFI 没有了 / WLAN 图标消失)

netsh int ip reset 命令是用于重置 Windows 操作系统中的网络设置和配置的命令。 在网络故障排除、修复网络连接问题以及清除可能存在的网络配置冲突时非常有用。 命令详解: netsh: 用于配置各种网络设置 int: 用于管理网络接口 ip: 用于管理网络接口的 IP 配…