06|调用模型:使用OpenAI API还是微调开源Llama2/ChatGLM?

06|调用模型:使用OpenAI API还是微调开源Llama2/ChatGLM?

img

让我们带着下面的问题来开始这一节课的学习。大语言模型,不止 ChatGPT 一种。调用 OpenAI 的 API,当然方便且高效,不过,如果我就是想用其他的模型(比如说开源的 Llama2 或者 ChatGLM),该怎么做?再进一步,如果我就是想在本机上从头训练出来一个新模型,然后在 LangChain 中使用自己的模型,又该怎么做?

关于大模型的微调(或称精调)、预训练、重新训练、乃至从头训练,这是一个相当大的话题,不仅仅需要足够的知识和经验,还需要大量的语料数据、GPU 硬件和强大的工程能力。别说一节课了,我想两三个专栏也不一定能讲全讲透。不过,我可以提纲挈领地把大模型的训练流程和使用方法给你缕一缕。这样你就能体验到,在 LangChain 中使用自己微调的模型是完全没问题的。

大语言模型发展史

说到语言模型,我们不妨先从其发展史中去了解一些关键信息。

Google 2018 年的论文名篇 Attention is all you need,提出了 Transformer 架构,也给这一次 AI 的腾飞点了火。Transformer 是几乎所有预训练模型的核心底层架构。基于 Transformer 预训练所得的大规模语言模型也被叫做“基础模型”(Foundation Model 或 Base Model)。

在这个过程中,模型学习了词汇、语法、句子结构以及上下文信息等丰富的语言知识。这种在大量数据上学到的知识,为后续的下游任务(如情感分析、文本分类、命名实体识别、问答系统等)提供了一个通用的、丰富的语言表示基础,为解决许多复杂的 NLP 问题提供了可能。

在预训练模型出现的早期,BERT 毫无疑问是最具代表性的,也是影响力最大的模型。BERT 通过同时学习文本的前向和后向上下文信息,实现对句子结构的深入理解。BERT 之后,各种大型预训练模型如雨后春笋般地涌现,自然语言处理(NLP)领域进入了一个新时代。这些模型推动了 NLP 技术的快速发展,解决了许多以前难以应对的问题,比如翻译、文本总结、聊天对话等等,提供了强大的工具。

img

各种预训练语言模型

当然,现今的预训练模型的趋势是参数越来越多,模型也越来越大,训练一次的费用可达几百万美元。这样大的开销和资源的耗费,只有世界顶级大厂才能够负担得起,普通的学术组织和高等院校很难在这个领域继续引领科技突破,这种现象开始被普通研究人员所诟病。

img

模型越来越大,参数越来越多

预训练 + 微调的模式

不过,话虽如此,大型预训练模型的确是工程师的福音。因为,经过预训练的大模型中所习得的语义信息和所蕴含的语言知识,能够非常容易地向下游任务迁移。NLP 应用人员可以对模型的头部或者部分参数根据自己的需要进行适应性的调整,这通常涉及在相对较小的有标注数据集上进行有监督学习,让模型适应特定任务的需求。

这就是对预训练模型的微调(Fine-tuning)。微调过程相比于从头训练一个模型要快得多,且需要的数据量也要少得多,这使得作为工程师的我们能够更高效地开发和部署各种 NLP 解决方案。

img

预训练+微调的应用模式

图中的“具体任务”,其实也可以更换为“具体领域”。那么总结来说:

  • 预训练:在大规模无标注文本数据上进行模型的训练,目标是让模型学习自然语言的基础表达、上下文信息和语义知识,为后续任务提供一个通用的、丰富的语言表示基础。
  • 微调:在预训练模型的基础上,可以根据特定的下游任务对模型进行微调。现在你经常会听到各行各业的人说:我们的优势就是领域知识嘛!我们比不过国内外大模型,我们可以拿开源模型做垂直领域嘛!做垂类模型!—— 啥叫垂类?指的其实就是根据领域数据微调开源模型这件事儿。

这种预训练 + 微调的大模型应用模式优势明显。首先,预训练模型能够将大量的通用语言知识迁移到各种下游任务上,作为应用人员,我们不需要自己寻找语料库,从头开始训练大模型,这减少了训练时间和数据需求;其次,微调过程可以快速地根据特定任务进行优化,简化了模型部署的难度;最后,预训练 + 微调的架构具有很强的可扩展性,可以方便地应用于各种自然语言处理任务,大大提高了 NLP 技术在实际应用中的可用性和普及程度,给我们带来了巨大的便利。

好,下面咱们开始一步步地使用开源模型。今天我要带你玩的模型主要是 Meta(Facebook)推出的 Llama2。当然你可以去 Llama 的官网下载模型,然后通过 Llama 官方 GitHub 中提供的方法来调用它。但是,我还是会推荐你从 HuggingFace 下载并导入模型。因为啊,前天百川,昨天千问,今天流行 Llama,明天不就流行别的了嘛。模型总在变,但是 HuggingFace 一直在那里,支持着各种开源模型。我们学东西,尽量选择学一次能够复用的知识。

用 HuggingFace 跑开源模型

注册并安装 HuggingFace

第一步,还是要登录 HuggingFace 网站,并拿到专属于你的 Token。(如果你做了前面几节课的实战案例,那么你应该已经有这个 API Token 了)

第二步,用 pip install transformers 安装 HuggingFace Library。详见这里。

第三步,在命令行中运行 huggingface-cli login,设置你的 API Token。

img

当然,也可以在程序中设置你的 API Token,但是这不如在命令行中设置来得安全。

# 导入HuggingFace API Token
import os
os.environ['HUGGINGFACEHUB_API_TOKEN'] = '你的HuggingFace API Token'

申请使用 Meta 的 Llama2 模型

在 HuggingFace 的 Model 中,找到 meta-llama/Llama-2-7b。注意,各种各样版本的 Llama2 模型多如牛毛,我们这里用的是最小的 7B 版。此外,还有 13b\70b\chat 版以及各种各样的非 Meta 官方版。

img

选择 meta-llama/Llama-2-7b 这个模型后,你能够看到这个模型的基本信息。如果你是第一次用 Llama,你需要申请 Access,因为我已经申请过了,所以屏幕中间有句话:“You have been granted access to this model”。从申请到批准,大概是几分钟的事儿。

img

通过 HuggingFace 调用 Llama

好,万事俱备,现在我们可以使用 HuggingFace 的 Transformers 库来调用 Llama 啦!

# 导入必要的库
from transformers import AutoTokenizer, AutoModelForCausalLM# 加载预训练模型的分词器
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-2-7b-chat-hf")# 加载预训练的模型
# 使用 device_map 参数将模型自动加载到可用的硬件设备上,例如GPU
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-7b-chat-hf", device_map = 'auto')  # 定义一个提示,希望模型基于此提示生成故事
prompt = "请给我讲个玫瑰的爱情故事?"# 使用分词器将提示转化为模型可以理解的格式,并将其移动到GPU上
inputs = tokenizer(prompt, return_tensors="pt").to("cuda")# 使用模型生成文本,设置最大生成令牌数为2000
outputs = model.generate(inputs["input_ids"], max_new_tokens=2000)# 将生成的令牌解码成文本,并跳过任何特殊的令牌,例如[CLS], [SEP]等
response = tokenizer.decode(outputs[0], skip_special_tokens=True)# 打印生成的响应
print(response)

这段程序是一个很典型的 HuggingFace 的 Transformers 库的用例,该库提供了大量预训练的模型和相关的工具。

  • 导入 AutoTokenizer:这是一个用于自动加载预训练模型的相关分词器的工具。分词器负责将文本转化为模型可以理解的数字格式。
  • 导入 AutoModelForCausalLM:这是用于加载因果语言模型(用于文本生成)的工具。
  • 使用 from_pretrained 方法来加载预训练的分词器和模型。其中,device_map = ‘auto’ 是为了自动地将模型加载到可用的设备上,例如 GPU。
  • 然后,给定一个提示(prompt):“请给我讲个玫瑰的爱情故事?”,并使用分词器将该提示转换为模型可以接受的格式,return_tensors=“pt” 表示返回 PyTorch 张量。语句中的 .to(“cuda”) 是 GPU 设备格式转换,因为我在 GPU 上跑程序,不用这个的话会报错,如果你使用 CPU,可以试一下删掉它。
  • 最后使用模型的 .generate() 方法生成响应。max_new_tokens=2000 限制生成的文本的长度。使用分词器的 .decode() 方法将输出的数字转化回文本,并且跳过任何特殊的标记。

因为是在本地进行推理,耗时时间比较久。在我的机器上,大概需要 30s~2min 产生结果。

img

这样的回答肯定不能直接用做商业文案,而且,我的意思是玫瑰花相关的故事,它明显把玫瑰理解成一个女孩的名字了。所以,开源模型,尤其是 7B 的小模型和 Open AI 的 ChatGPT 还是有一定差距的。

LangChain 和 HuggingFace 的接口

讲了半天,LangChain 未出场。下面让我们看一看,如何把 HuggingFace 里面的模型接入 LangChain。

通过 HuggingFace Hub

第一种集成方式,是通过 HuggingFace Hub。HuggingFace Hub 是一个开源模型中心化存储库,主要用于分享、协作和存储预训练模型、数据集以及相关组件。

我们给出一个 HuggingFace Hub 和 LangChain 集成的代码示例。

# 导入HuggingFace API Token
import os
os.environ['HUGGINGFACEHUB_API_TOKEN'] = '你的HuggingFace API Token'# 导入必要的库
from langchain import PromptTemplate, HuggingFaceHub, LLMChain# 初始化HF LLM
llm = HuggingFaceHub(repo_id="google/flan-t5-small",#repo_id="meta-llama/Llama-2-7b-chat-hf",
)# 创建简单的question-answering提示模板
template = """Question: {question}Answer: """# 创建Prompt          
prompt = PromptTemplate(template=template, input_variables=["question"])# 调用LLM Chain --- 我们以后会详细讲LLM Chain
llm_chain = LLMChain(prompt=prompt,llm=llm
)# 准备问题
question = "Rose is which type of flower?"# 调用模型并返回结果
print(llm_chain.run(question))

可以看出,这个集成过程非常简单,只需要在 HuggingFaceHub 类的 repo_id 中指定模型名称,就可以直接下载并使用模型,模型会自动下载到 HuggingFace 的 Cache 目录,并不需要手工下载。

初始化 LLM,创建提示模板,生成提示的过程,你已经很熟悉了。这段代码中有一个新内容是我通过 llm_chain 来调用了 LLM。这段代码也不难理解,有关 Chain 的概念我们以后还会详述。

不过,我尝试使用 meta-llama/Llama-2-7b-chat-hf 这个模型时,出现了错误,因此我只好用比较旧的模型做测试。我随便选择了 google/flan-t5-small,问了它一个很简单的问题,想看看它是否知道玫瑰是哪一种花。

img

模型告诉我,玫瑰是花。对,答案只有一个字,flower。这…不得不说,2023 年之前的模型,和 2023 年之后的模型,水平没得比。以前的模型能说话就不错了。

img

ChatGPT 本 T 的回答

通过 HuggingFace Pipeline

既然 HuggingFace Hub 还不能完成 Llama-2 的测试,让我们来尝试另外一种方法,HuggingFace Pipeline。HuggingFace 的 Pipeline 是一种高级工具,它简化了多种常见自然语言处理(NLP)任务的使用流程,使得用户不需要深入了解模型细节,也能够很容易地利用预训练模型来做任务。

让我来看看下面的示例:

# 指定预训练模型的名称
model = "meta-llama/Llama-2-7b-chat-hf"# 从预训练模型中加载词汇器
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained(model)# 创建一个文本生成的管道
import transformers
import torch
pipeline = transformers.pipeline("text-generation",model=model,torch_dtype=torch.float16,device_map="auto",max_length = 1000
)# 创建HuggingFacePipeline实例
from langchain import HuggingFacePipeline
llm = HuggingFacePipeline(pipeline = pipeline, model_kwargs = {'temperature':0})# 定义输入模板,该模板用于生成花束的描述
template = """为以下的花束生成一个详细且吸引人的描述:花束的详细信息:```{flower_details}```"""# 使用模板创建提示
from langchain import PromptTemplate,  LLMChain
prompt = PromptTemplate(template=template, input_variables=["flower_details"])# 创建LLMChain实例
from langchain import PromptTemplate
llm_chain = LLMChain(prompt=prompt, llm=llm)# 需要生成描述的花束的详细信息
flower_details = "12支红玫瑰,搭配白色满天星和绿叶,包装在浪漫的红色纸中。"# 打印生成的花束描述
print(llm_chain.run(flower_details))

这里简单介绍一下代码中使用到的 transformers pipeline 的配置参数。

img

生成的结果之一如下:

img

此结果不敢恭维。但是,后续的测试告诉我,这很有可能是 7B 这个模型太小,尽管有形成中文的相应能力,但是能力不够强大,也就导致了这样的结果。

至此,通过 HuggingFace 接口调用各种开源模型的尝试成功结束。下面,我们进行最后一个测试,看看 LangChain 到底能否直接调用本地模型。

用 LangChain 调用自定义语言模型

最后,我们来尝试回答这节课开头提出的问题,假设你就是想训练属于自己的模型。而且出于商业秘密的原因,不想开源它,不想上传到 HuggingFace,就是要在本机运行模型。此时应该如何利用 LangChain 的功能?

我们可以创建一个 LLM 的衍生类,自己定义模型。而 LLM 这个基类,则位于 langchain.llms.base 中,通过 from langchain.llms.base import LLM 语句导入。

这个自定义的 LLM 类只需要实现一个方法:

  • _call 方法:用于接收输入字符串并返回响应字符串。

以及一个可选方法:

  • _identifying_params 方法:用于帮助打印此类的属性。

下面,让我们先从 HuggingFace 的这里,下载一个 llama-2-7b-chat.ggmlv3.q4_K_S.bin 模型,并保存在本地。

img

你可能会质疑我,不是说自己训练,自己微调,不再用 HuggingFace 了吗?

不好意思,容许我解释一下。自己训练一个能用的模型没那么容易。这个模型,它并不是原始的 Llama 模型,而是 TheBloke 这位老兄用他的手段为我们量化过的新模型,你也可以理解成,他已经为我们压缩或者说微调了 Llama 模型。

量化是 AI 模型大小和性能优化的常用技术,它将模型的权重简化到较少的位数,以减少模型的大小和计算需求,让大模型甚至能够在 CPU 上面运行。当你看到模型的后缀有 GGML 或者 GPTQ,就说明模型已经被量化过,其中 GPTQ 是一种仅适用于 GPU 的特定格式。GGML 专为 CPU 和 Apple M 系列设计,但也可以加速 GPU 上的某些层。llama-cpp-python 这个包就是为了实现 GGML 而制作的。

所以,这里你就假设,咱们下载下来的 llama-2-7b-chat.ggmlv3.q4_K_S.bin 这个模型,就是你自己微调过的。将来你真的微调了 Llama2、ChatGLM、百川或者千问的开源版,甚至是自己从头训练了一个 mini-ChatGPT,你也可以保存为 you_own_model.bin 的格式,就按照下面的方式加载到 LangChain 之中。

然后,为了使用 llama-2-7b-chat.ggmlv3.q4_K_S.bin 这个模型,你需要安装 pip install llama-cpp-python 这个包。

# 导入需要的库
from llama_cpp import Llama
from typing import Optional, List, Mapping, Any
from langchain.llms.base import LLM# 模型的名称和路径常量
MODEL_NAME = 'llama-2-7b-chat.ggmlv3.q4_K_S.bin'
MODEL_PATH = '/home/huangj/03_Llama/'# 自定义的LLM类,继承自基础LLM类
class CustomLLM(LLM):model_name = MODEL_NAME# 该方法使用Llama库调用模型生成回复def _call(self, prompt: str, stop: Optional[List[str]] = None) -> str:prompt_length = len(prompt) + 5# 初始化Llama模型,指定模型路径和线程数llm = Llama(model_path=MODEL_PATH+MODEL_NAME, n_threads=4)# 使用Llama模型生成回复response = llm(f"Q: {prompt} A: ", max_tokens=256)# 从返回的回复中提取文本部分output = response['choices'][0]['text'].replace('A: ', '').strip()# 返回生成的回复,同时剔除了问题部分和额外字符return output[prompt_length:]# 返回模型的标识参数,这里只是返回模型的名称@propertydef _identifying_params(self) -> Mapping[str, Any]:return {"name_of_model": self.model_name}# 返回模型的类型,这里是"custom"@propertydef _llm_type(self) -> str:return "custom"# 初始化自定义LLM类
llm = CustomLLM()# 使用自定义LLM生成一个回复
result = llm("昨天有一个客户抱怨他买了花给女朋友之后,两天花就枯了,你说作为客服我应该怎么解释?")# 打印生成的回复
print(result)

代码中需要解释的内容不多,基本上就是 CustomLLM 类的构建和使用,类内部通过 Llama 类来实现大模型的推理功能,然后直接返回模型的回答。

img

似乎 Llama 经过量化之后,虽然仍读得懂中文,但是不会讲中文了。

翻译成中文,他的回答是这样的。

当客户抱怨他们为女朋友买的花在两天内就枯萎了,我会以礼貌和专业的方式这样解释:

“感谢您把这个问题告诉我们。对于给您带来的任何不便,我深感抱歉。有可能这些花没有被正确地存储或照料,这可能影响了它们的生命期。我们始终以提供高质量的产品为荣,但有时可能会出现意外的问题。请您知道,我们非常重视您的满意度并随时为您提供帮助。您希望我为您提供替换或退款吗?”

看上去,除了中文能力不大灵光之外,Llama2 的英文表现真的非常完美,和 GPT3.5 差距不是很大,要知道:

  1. 这可是开源模型,而且是允许商业的免费模型。
  2. 这是在本机 CPU 的环境下运行的,模型的推理速度还是可以接受的。
  3. 这仅仅是 Llama 的最小版本,也就是 7B 的量化版,就达到了这么好的效果。

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

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

相关文章

掌握成功的关键:了解定位咨询如何让你的业务转型和增长

在当今的商业世界中,市场竞争变得前所未有的激烈。这不仅要求企业提供优质的产品和服务,还需要确保其在市场中的位置。在这种环境中,精确的市场定位不仅是一个优势,而是生存和发展的必需。 定位咨询的概念与重要性 定位咨询是一项…

Java程序设计中的猴子选大王

涉及思想 参选猴子按照1,2,……,n编号并按照顺序围成一圈,从第k只猴子起,由1开始报数,报到m时,该猴子就跳出圈外,下一只猴子再次从 1开始进行报数,如此循环,…

逻辑卷学习

磁盘分区的缺点 1.无法扩容 2.必须使用的空间 3.没有备份: 一、逻辑卷的定义 LVM 是 Logical Volume Manager 的简称,译为中文就是逻辑卷管理。它是 Linux 下对硬盘分区的一种管理机制。LVM 适合于管理大存储设备,并允许用户动态调整文件系统的大小…

C#多条件排序OrderBy、ThenBy

方法和效果 有多个排序条件,其实不用单独自己写排序方法的,C#内置了排序方法: 引用命名空间System.Linq 正向排序的方法:OrderBy首要条件;ThenBy次要条件,可以连续多个使用 同理,逆向排序对应…

Axios安装及使用【基础篇】

Axios安装及使用 安装Axios搭建虚拟后台Axios的使用 安装Axios 使用npm安装:npm install axios 搭建虚拟后台 使用npm安装: npm install -g json-server创建一个json-server的文件夹,并创建一个db.json的文件db.json文件 配置相关数据: 启…

Lunix的奇妙冒险————权限篇

文章目录 一.什么是权限二.用户权限和类别。1.用户2.角色3.更换文件角色 三.文件的类别和对应权限1.文件的类别。2.文件属性权限1.权限说明。2.默认生成文件权限来源3.更改权限 3.文件的执行与删除 四.不同用户共同在一个目录下的权限。1.普通用户家目录2.在同一目录下文件的权…

十二:爬虫-Scrapy框架(上)

一:Scrapy介绍 1.Scrapy是什么? Scrapy 是用 Python 实现的一个为了爬取网站数据、提取结构性数据而编写的应用框架(异步爬虫框架) 通常我们可以很简单的通过 Scrapy 框架实现一个爬虫,抓取指定网站的内容或图片 Scrapy使用了Twisted异步网…

方案:智能分析网关V4区域人数超员AI算法模型的应用场景介绍

视频AI智能分析技术已经深入到人类生活的各个角落,与社会发展的方方面面紧密相连。从日常生活中的各种场景,如人脸识别、车牌识别,到工业生产中的安全监控,如工厂园区的翻越围栏识别、入侵识别、工地的安全帽识别、车间流水线产品…

低代码平台搭建ERP系统 低代码快速开发灵活的ERP

随着数字化时代的到来,企业迫切需要高效、灵活的ERP系统来提高运营效率。在这一背景下,白码低代码平台成为了企业实现数字化转型的首选工具。本文将介绍低代码开发ERP的概念,并以白码低代码平台为例,探讨其在企业数字化转型中的重…

基于ssm潍坊理工学院就业信息网的设计与实现论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本潍坊理工学院就业信息网就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数…

Python 为UnityAndroid端自动化接入Tradplus广告SDK

Python 为UnityAndroid端自动化接入Tradplus广告SDK Tradplus介绍常规接入进入Android开发文档选择渠道配置生成接入代码人工依赖下载官网同版本的 Unity插件 使用自动化工具接入首次 你需要打两个标记来定位运行工具 控制台会列出最新的十个Tradplus版本 任选其一然后拖入项目…

一文详解Cookie以及Selenium自动获取Cookie

前言 以后数据获取途径以及数据资产绝对会是未来核心要素生产工具和资源之一,每个大模型都离不开更加精细化数据的二次喂养训练。不过现在来看收集大量数据的方法还是有很多途径的,有些垂直领域的专业数据是很难获取得到的,靠人力去搜寻相当…

【代码随想录】刷题笔记Day42

前言 这两天机器狗终于搞定了,一个控制ROS大佬,一个计院编程大佬,竟然真把创新点这个弄出来了,牛牛牛牛(菜鸡我只能负责在旁边喊加油)。下午翘了自辩课来刷题,这次应该是元旦前最后一刷了&…

2023年度总结(找到工作)

转眼2023年结束了,今天已经12月29日了。从2022年12月25日考研失败后,2023年就变成了找工作以及上班度日的时光了。针对2023年,我想对自己所说的是:终于找到工作了。作为一个普通的专升本,考研落榜生来说,能…

电子工程师如何接私活赚外快?

对电子工程师来说,利用业余时间接私活是个很常见的技术,不仅可以赚取额外收入,也能提升巩固技术,可以说国内十个工程师,必有五个在接私活养家糊口,如果第一次接私活,该如何做? 很多工…

Mybatis行为配置之Ⅲ—其他行为配置项说明

专栏精选 引入Mybatis Mybatis的快速入门 Mybatis的增删改查扩展功能说明 mapper映射的参数和结果 Mybatis复杂类型的结果映射 Mybatis基于注解的结果映射 Mybatis枚举类型处理和类型处理器 再谈动态SQL Mybatis配置入门 Mybatis行为配置之Ⅰ—缓存 Mybatis行为配置…

力扣:968. 监控二叉树(贪心,二叉树)

题目: 给定一个二叉树,我们在树的节点上安装摄像头。 节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。 计算监控树的所有节点所需的最小摄像头数量。 示例 1: 输入:[0,0,null,0,0] 输出:1 解释&…

iPortal内置Elasticsearch启动失败的几种情况——Linux

作者:yx 文章目录 前言一、端口占用二、ES启动过慢三、磁盘占用过高,导致ES变为只读模式 前言 在Linux环境启动iPortal后有时会出现搜索异常的情况,如下截图,这是因为Elasticsearch(以下简称“ES”)没启动…

集群部署篇--Redis 主从模式

文章目录 前言Redis 主从部署:1.1 主从架构 介绍:1.2 主从架构 实现:1.2.1 redis 安装: 1.3 主从架构优缺点:1.4 故障转移: 总结 前言 显然在线上环境中 Redis 服务不能以单机的方式运行,必须有…

华为发布的工业软件三大难题:适用于CAD领域的NURBS裁剪曲面自交快速检测

以下内容转载: 自相交,在几何图形有效性验证中的一个错误类型,面要素的自相交在原始数据中是最常见的,这种错误有些可以人工发现,但有些就需要借助程序来发现。 发生自相交的根本原因情况比较多,有些是因为…