使用 OpenLLM 构建和部署大模型应用

原文:使用 OpenLLM 构建和部署大模型应用 - 知乎

分享主题为:使用 OpenLLM 快速构建和部署大语言模型的应用。OpenLLM 是一个开源的大语言模型(LLM)开发框架。它支持多种开源的 LLM 模型,并且具有内建的两个关键的 LLM 优化,能够优化内存使用。此外,它与 LangChain 和 BentoML 都有很好的集成,可以快速地构建和部署大语言模型的应用。

今天的分享会围绕下面五点展开:

1. BentoML 公司简介

2. OpenLLM 产品背景

3. OpenLLM 介绍、应用举例与使用优势

4. BentoML 介绍与应用举例

5. OpenLLM 总结

分享嘉宾|明希 BentoML 高级软件工程师

编辑整理|张阳

内容校对|李瑶

出品社区|DataFun

01BentoML 公司简介

BentoML专注于提供机器学习基础设施。核心产品是与公司同名的开源框架BentoML。公司总部位于旧金山湾区,在国内也有众多远程工作的同事。通过不断努力,公司获得了众多客户的认可。

02OpenLLM 产品背景

首先来分享一下我们开发 OpenLLM 的背景。

1. LLM 爆发

相信即将过去的 2023 年对大家来说都是非常奇妙的一年。2022 年 11 月的时候 ChatGPT 刚刚发布,过了一年到现在,我们已经见证了各种各样的大语言模型横空出世:有商用的大语言模型,比如 Claude 和 GPT;也有很多开源的小模型,其参数量可能从几个 B 到几百个 B 不等。可以说这是一个大语言模型繁荣发展的时代,新型语言模型的层出不穷。

BentoML 在与一些客户互动时发现,他们在开发过程中可能会利用 OpenAI 的能力进行开发,将数据输入到 prompt 中,然后测试推理结果。在将模型部署到生产环境上线时,他们希望在自己的服务器或云服务器上进行部署。

2. 属于自己的 LLM

大部分客户有以下诉求:

  • 高可控性/灵活性:如果将所有数据作为一个 prompt 输入到 OpenAI 的模型中进行推理,这种方法可能并不太切实际。最终,他们期望能够通过自行训练或微调,利用多年来积累的用户数据得到一个属于自己的模型,实现更加灵活的推理需求。
  • 数据安全性:如果将自己的数据用于模型推理,就需要关注数据安全性的问题。因为如果使用的是公共网络上的模型,就不可避免地需要将自己的私有数据输入到这个公共网络的模型中。这可能导致数据泄露的问题,在一些注重数据安全性的企业中,这是无法接受的。
  • 成本效益:正如之前提到的,如果使用通用模型并采用经过优化的 prompt,可能需要一个庞大的 prompt。举例来说,如果要进行文档的推理,可能需要将整个文档或一本书输入到 prompt 中。目前大多数商业模型是按 Token 计费的,如果提示非常庞大,成本就会相应增加。然而,如果你能够拥有自己的大模型应用,那么成本可能只涉及硬件费用。并且,其精确度可能更高,这意味着你可能只需使用更小的模型就能达到相同的推理准确度,从而进一步降低成本。

3. 生产环境中部署 LLMs 的挑战

如果我们自己去部署大语言模型,可能会遇到以下挑战:

  • 可操作性:主要涉及到硬件成本,即一个大型模型是否能够有效地部署在特定硬件上。我们都知道,一些优秀的显卡可能不太容易获取。举例来说,一个拥有 13B 参数的模型,其参数总量可能需要 26GB,这就使得单卡 A10G 显卡难以应对。因此,可能需要考虑使用多卡或多机部署来解决硬件上的限制。
  • 可扩展性:包含硬件可扩展性和软件可扩展性两个方面。首先是硬件的可扩展性,指的是在请求量和并发数较低时,可以只需一颗显卡或一台机器来满足需求,而在用户量增大时,希望系统能够自动启用多颗显卡或多台机器进行并发推理。第二方面是软件的可扩展性。考虑到现在有许多大型语言模型,你可能在开发或测试阶段希望方便地在不同模型之间切换,以观察它们的效果并进行比较。这就需要软件方面的可扩展性。
  • 吞吐量:大型语言模型的应用与传统的机器学习应用有一些区别。传统的机器学习应用,比如图像分类任务,通常可以进行批处理,即一次性处理多个输入,同时返回结果。但是大型语言模型在推理时,其输入不是同时到达,输出也不是同时产生,这给吞吐量带来了更大的挑战。
  • 延迟:我们自然希望延迟越低越好,但在机器学习应用中,延迟有时与吞吐量是一对相互制衡的指标。换句话说,如果要达到较大的吞吐量,可能需要在一定程度上牺牲延迟。

03OpenLLM 介绍、应用举例与使用优势

1. OpenLLM 介绍

下面介绍我们的开源产品 OpenLLM 是如何解决上述问题的。

OpenLLM 于 2023 年 6 月开源,是一个用于部署大语言模型的框架。目前,该项目在 GitHub 上已经获得了 6800 多个星标。其最初的口号是通过一行代码或相对轻松地在不同的大语言模型之间切换,为个人用户提供方便。无论是想要尝试不同模型的个人用户,还是想要部署自己的 AI 应用的用户,OpenLLM 都可以提供便捷的解决方案。

OpenLLM 目前支持几乎所有常用的开源大语言模型。对于每个模型,框架都提供了多个不同的参数量和不同部署模型 ID 可供选择。目前包括 ChatGLM、百川、Dolly-V2 等模型。

2. OpenLLM 应用举例

接下来通过演示来介绍 OpenLLM 是如何加速大语言模型应用的开发和部署的。

首先,启动一个 LLM 服务。

启动 LLM 服务非常简单,只需在安装 LLM 工具后运行以下命令:"start dolly-v2" 即可启动应用。如果你的计算机上之前未下载过该模型,它将自动帮你下载。这可能需要一些时间,应用启动后,可以通过命令行直接与该服务交互,提出一个问题,比如"地球的重量是多少"。我们使用的是 Dolly-V2 模型,它给出了一个回答。由于这个模型相对较弱,因此回答可能不太准确。

我们尝试使用另一个模型,LlaMA,来看看是否可以提升准确度。在这里,我们选择使用 LlaMA2 模型,但由于 LlaMA2 不是 LlaMA 的默认模型,我们需要指定一下模型 ID。和之前一样,使用方法完全相同,只是切换了模型。

因此,使用我们的框架,用户可以轻松在不同的模型之间切换。尽管使用方法一样,但不同模型的回答可能会有所不同。这次使用 LlaMA2 模型,可以看到给出的答案相对更准确。

我们使用命令行与服务进行交互,这在测试阶段非常方便和实用。然而,在实际部署应用时,我们可能希望应用提供一个 HTTP 或 gRPC 接口,以便前端或外部系统能够调用。

OpenLLM 框架支持内置的开箱即用的 HTTP API。在服务的首页,显示一个 Swagger 页面,列出了所有服务支持的 HTTP 端点。你甚至可以在这里直接与服务进行交互和测试,输入提示并获取 JSON 格式的响应体,就像我们之前在命令行中演示的一样。

由于我们暴露了 HTTP 接口,因此无论使用 Python、Node 还是 Curl 等任何能够访问 HTTP 的客户端,都可以调用这个接口。这为应用的灵活性和可访问性提供了更多的选择。

我们还提供了一个 Python SDK,使用户能够在 Python 代码中直接与服务进行交互。只需导入 Client,指定服务的地址,就可以直接向服务提出问题,它将正确地给出答案。这样就可以在 Python 环境中更加便捷地集成和使用 OpenLLM 的服务。

3. OpenLLM 使用优势

使用 OpenLLM 有以下优势:

  • 模型切换。用户能够方便地在不同的模型之间进行切换。
  • 内置多种优化技术。首先是量化,通过减少参数精度来降低整体内存使用,特别适用于大型语言模型。OpenLLM 支持几乎所有模型的量化。其次是 Token Streaming 技术,在典型的聊天机器人场景中表现出色,允许边产生边接收答案,词汇逐个生成。还有 continuous batching(持续批跑)和 paged attention 等重要优化。
  • 多卡支持。用户可以指定多个 GPU,并根据需要选择运行方式,甚至可以指定特定的GPU。
  • 模型表现监测。基于公司产品 BentoML,支持 Metrics 测量和性能指标监控。
  • 支持模型微调推理。OpenLLM 支持 Fine-tune,同时也支持与 LoRA Layer 进行合作的推理。
  • 与其他 AI 工具如 BentoML、LangChain 和 Hugging Face 集成良好,提供了更全面的功能和应用场景。

下面重点讨论一下 Continuous Batching(持续批跑),因为我们使用了 VLM 的后端,它为我们带来了很好的优化。

在大型语言模型的推理中,输入的强度并不相同,有些输入可能更快产生结果,而有些可能需要更长时间。如果不进行优化,当其中一个输入(比如 S2)先完成推理时,整个过程就会等待其他输入完成才能进入下一轮。这会导致 GPU 时间的浪费,因为有一段时间没有推理任务在进行。

Continuous Batching 的优化可以在一个推理结束时立即引入下一个推理任务。以一个例子来说明,假设 S3 先完成了推理,那么 S5 就会立即加入,接着 S1 完成了推理,S6 就会立即加入。这样可以确保在每个时间片上都有一个模型推理任务在运行,从而最大程度地利用 GPU 资源。这是一个有效的优化策略,减少了空闲时间,提高了整体推理效率。

介绍了时间优化之后,再来看一下空间优化,尤其是关于 KVcache 的优化。首先简要介绍一下大语言模型的工作原理。它基于 Transformer 框架,模型通过一系列输入的 token,返回下一个 token 的最大概率。然而,由于输入可能存在重复计算,例如在输入"我是一只"后,模型返回"我是一只猫",在输入"我是一只猫"时,又返回"我是一只猫,",这导致了 Transformer 框架中有许多重复的计算。为了解决这个问题,我们使用 KVcache 缓存计算结果。

KVcache 带来了一个新问题,就是在计算机内存分配时,无法准确知道需要分配多少内存。我们只能先估算一个大致的范围。通过图表演示可以看到,当一个任务完成后,本来可以释放的内存却可能由于下一个任务的加入而无法充分利用。这样就会产生很多内存碎片,影响内存的使用效率。

为了优化这个问题,引入了 Paged Attention。Paged Attention 的优化思想是将所有内存拆分成一个个 block,然后在内存分配时按 block 分配。如果一个任务完成后,发现内存不够,需要再增加时,框架会在另一个地方(可能不是连续的地方)分配另一个 block。任务完成后,这个 block 可能会被释放,供下一个任务使用。通过这种方式,可以有效减少内存碎片。需要注意的是,内存不是连续的,因此需要一个 block table 来存储内存的物理位置和实际序号的映射关系,使得在大模型中看起来是获得了一个逻辑上连续的内存。

04BentoML 介绍与应用举例

1. BentoML 介绍

完成了以上优化后,开始部署大语言模型。然而,大多数 AI 应用不仅仅是将一个模型部署上去,否则没有哪个公司能够与 OpenAI 竞争。因此,除了模型推理之外,我们的 AI 应用还可能包含许多其他方面的工作。例如,需要考虑如何收集数据、验证数据、配置部署指标以及如何进行模型推理,包括服务指标的观测。这些问题在研究阶段,可能不需要考虑,但在部署和工程化之后,必须考虑这些杂项问题。

BentoML 与 OpenLLM 集成带来了许多优势。BentoML 是一个专注于解决部署后事项的开源 AI 部署框架,具体如下:

  • 开源 AI 部署框架:BentoML 提供了一整套的开发、部署和打包解决方案。
  • 模型与代码的版本控制:BentoML 引入了模型和版本的控制概念,使得模型可以像 GitHub 的提交一样进行版本控制。由此可以轻松追踪和回退之前的指定版本,特别是在模型出错时非常有用。
  • 通过 Metrics、Traces 和 Logs 提供开箱即用的可观察性:BentoML 内置了开箱即用的可观测性功能,包括测量指标、追踪和日志功能,帮助用户更好地监测和理解模型的性能。
  • 容器化为标准的 OCI 镜像:BentoML 支持将整个机器学习应用打包为标准的容器镜像。
  • 多种部署目标:可以将应用轻松部署在各种云服务器上,例如 AWS。
  • 分布式部署与扩容:BentoML 支持分布式的部署与扩容,为处理高负载提供了便利。
  • Serverless BentoCloud:这是 BentoML 最新支持的功能之一,允许以 Serverless 方式的部署。这意味着应用在没有任何请求时不占用任何资源,只有在第一个请求到达时才进行冷启动。

BentoML 模型是对机器学习模型的一种抽象。在机器学习领域,有许多不同的框架,每个框架都有自己的模型概念。BentoML 允许将这些不同框架的模型导入为 BentoML 模型。这种抽象化的设计有几个优点:

  • 版本管理:BentoML 模型具有版本管理功能,这意味着可以轻松地追踪、管理和回滚模型的不同版本。这对于模型的迭代和更新非常有用。
  • 团队协作:在开发 AI 应用时,通常会有研究团队负责训练模型。一旦模型被训练并保存为 BentoML 模型,就可以被推送到远程平台,供工程团队下载和使用。这种分工和协作的方式使得团队可以更加高效地合作,研究和工程团队可以专注于各自的任务。通过这种方式,团队成员不需要担心模型的具体来源,只需通过 BentoML 平台下载并使用相应的模型。这种团队协作的概念有助于提高整个开发过程的效率和协同工作的流畅性。

BentoML 的 Runner 具有以下特点:

  • Remote Worker:Runner 将模型封装成一个远程对象,使其可以对外提供服务。这种分离的设计允许模型独立于应用部署,提高了系统的模块化性和可维护性。
  • 独立扩容:由于 AI 应用的模型部分通常需要大量 GPU 资源,而其他任务如 API 接口、数据预处理和 IO 操作等则可能只需要 CPU。通过独立部署,它们可以相互独立地扩容。CPU 资源相对便宜,可以自由扩展,而 GPU 资源可能有限,例如只有 2 到 3 个。这种方式可以确保将 GPU 资源专注于模型推理,而将 CPU 资源用于其他任务,提高了整体的资源利用率。
  • 支持主流 ML 框架直接转化为 Runner:BentoML 支持几乎所有主流的机器学习框架,包括 PyTorch 和 TensorFlow。模型可以直接转换为 Remote Runner,并在独立的进程中进行部署。

上图中展示了 BentoML API Server 的工作流程:应用从外部接收 HTTP 请求,可能是通过 POST 方法发送的 JSON 数据。接收到的 HTTP 请求数据可能需要进行预处理,以便转换为模型能够接受的格式。这个步骤通常涉及数据格式转换、验证等操作,确保输入数据符合模型的要求。IO Descriptors 定义了输入和输出数据的结构和类型,起到了数据格式转换桥梁的作用。经过 IO Descriptors 的转换后,数据被传递给模型进行推理。模型利用输入数据生成相应的预测或输出。模型的输出可能需要进行一些后置处理,以便将其转换为 HTTP 响应的格式。这个步骤包括将 Tensor 或 Numpy 数组转换为 JSON 格式等。处理完后的数据以 HTTP 响应的形式返回给请求方,完成了整个推理过程。这是应用与外部系统通信的出口。

BentoML 的请求处理流程经过了负载均衡层、API 服务器和 Runner 的多个层次:

  • 负载均衡层:负载均衡层接收到所有的请求,并负责将它们分发给 API 服务器。这一层可以进行请求的智能分发,确保每个 API 服务器负载均衡。
  • API 服务器:API 服务器是 BentoML 应用的入口,负责接收来自负载均衡层的请求。API 服务器可能会横向扩展,即创建多个实例以处理大量的并发请求。一旦 API 服务器接收到请求,它会进行一些预处理,然后将请求转发给 Runner。
  • Runner:Runner 是对模型的封装,负责实际的模型推理。在这一层,模型推理支持批处理功能。当 Runner 接收到一个请求时,它会等待一段时间,看是否有其他请求到达。只有当等待时间达到最大值或者达到了规定的批处理容量时,Runner 才会一次性提交这批请求给模型进行推理。这个过程对用户是无感知的,而且可以提高推理的效率。

这里介绍一下 BentoML 中 Bento 的概念,Bento 是打包好的最小的部署的单元,包括机器学习的依赖、环境的 Dockerfile、源代码、需要的模型等各种部署的配置。

2. BentoML 应用举例

接下来通过一个实例来演示如何使用 BentoML 开发和部署 AI 应用。我们将创建一个应用,利用 LangChain 和 OpenLLM 实现广告词的生成功能,并展示 LangChain 和 OpenLLM 的集成。然后,我们将使用 BentoML 启动一个 HTTP 服务,通过一行代码切换 LLM 模型,并最终生成一个 Bento 包,以演示如何使用 BentoML 进行后续部署。

在前面的代码中,我们导入了一些 LangChain 的模块。如果你对 LangChain 比较熟悉的话,应该对这些模块有所了解,这里不做详细讲解。接下来是 BentoML 的部分。BentoML 主要导入了一些 IO Descriptor,这些描述符用于说明输入输出的类型。在这里,我们导入了两个类型,一个是 JSON,另一个是 Text。现在我们将利用这些导入的模块和描述符,因为我们的输入应该是 JSON 格式,而输出则是一段文字。

接下来,我们将使用 pydantic 的 Model 定义一个结构体,该结构体用于验证输入的有效性。这个 Query 对象包含以下几个参数:industry 表示所在行业,productName 表示产品名称,keywords 表示需要的关键词。这些参数是生成广告词所需的输入。

第二部分是一个 helper 函数,用于快速切换模型 ID。该函数返回一个 LangChain 对象。因此,我们首先使用 opt 模型,如果注释掉上面的一行并使用下面一行,就可以直接切换到使用百川模型。

这是 Prompt 的生成部分,利用 LangChain 的功能,指定一个 Prompt 的模板,然后将刚才输入的参数填充到这个模板中,生成一个完整的 Prompt。

接下来的步骤是定义要公开的接口。通过指定输入和输出的类型,将这个函数作为服务的一个接口。在第 48 行,将 LLM 的 Runner 传递给了这个服务,因为在启动服务时,需要知道有哪些 Runner 需要在分布式环境中远程启动。因此,这里的启动会生成两个独立的服务:一个是 API 接口层(`Service`),另一个是 LLM Runner。它们是相互独立的。

启动之后,可以看到与之前相似的 Swagger 页面,我们可以直接在上面进行测试。在这里,我们将行业设为"SAAS",产品名称设为"BentoML",执行后,它可以为我们生成一段广告词。这个广告词符合我们的需求,看起来像一条推文或者微信的内容。如果我们想生成一个房地产行业的广告,只需切换行业为"房地产",就可以得到一条看起来更符合房地产行业的广告,其中还包含一个房子的表情图标。

开发以及本地的测试完成后,将整个代码和模型打包成一个 Bento。通过使用 BentoML 的 Build 命令,可以轻松制作一个 Bento 包。制作完成后,还有两个后续的可选步骤。

第一个是将其容器化 containerize,打包成一个镜像,为后续的部署使用。

第二种选择是可以直接把这个 Bento push 到我们的 Cloud 平台上,Cloud 平台会自动帮你执行后续的部署操作。

Cloud 平台是一个能够部署你的 Bento 的平台。它会将 Bento 自动转化为一个运行在 Kubernetes 上的容器,并在其上运行。这里的例子包括一个 API 服务器以及多个不同的 runner,包括 LLM 的 runner 和 Text2Image 的 runner 等。此外,在 BentoCloud 上,可以指定扩容的方式,可以分别为 API 指定需要扩容的节点数,或者为每个 runner 指定需要的 GPU 数量或实例数。

05OpenLLM 总结

OpenLLM 是一个开源的大语言模型(LLM)开发框架。它支持多种开源的 LLM 模型,并且具有内建的两个关键的 LLM 优化,能够优化内存使用。此外,它与 LangChain 和 BentoML 都有很好的集成。

以上就是本次分享的内容,谢谢大家。

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

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

相关文章

自然语言处理研究的内容

一.基础技术 1.1 词法分析 词法分析(Lexical Analysis),也称为词法扫描或扫描器,是自然语言处理(NLP)中的基础步骤之一,用于将输入的文本分割成词法单元(Token)。词法单…

vulnhub-dc2靶场

DC2 配置环境vmware17 nat网络配置 下载地址:DC and Five86 Series Challenges - DC-1 (似乎从2024/1/18左右找不到这个资源了) 攻击机kali与其在同一网段下 ip:192.168.52.130 信息收集 arp-scan -l #内网探测,扫描目标ip发现目标ip1…

【服务器】搭建一台属于自己的服务器

​🌈个人主页:Sarapines Programmer🔥 系列专栏:【服务器】搭建网站⏰诗赋清音:云生高巅梦远游, 星光点缀碧海愁。 山川深邃情难晤, 剑气凌云志自修。 目录 1. 购买服务器和域名 1.1 购买服务器 1.1.1 阿里云服务器 1.1.2 香草云服务器 1.2 购买域名 2. 安装宝塔…

Blender——将模型及其所有纹理与材质导入unity

前期准备 参考视频:7分钟教会你如何将Blender的模型材质导入unity_哔哩哔哩_bilibili 实验模型官网下载地址:Hoi An Ancient House Model free VR / AR / low-poly 3D model CSDN下载链接: 【免费】Blender三维模型-古代房屋模型&#xff…

【Linux】第三十三站:日志

文章目录 一、实现一个简单的日志1.简介2.可变参数3.错误等级4.时间5.打印每一条参数6.与前面的一些代码搭配使用 二、完整代码 一、实现一个简单的日志 1.简介 我们运行代码的时候,我们希望有各种各样的运行时候的一些信息。这也就是日志 它一半有日志时间&…

【GitHub项目推荐--老照片变清晰】【转载】

先来看一个效果图,这个开源项目能把模糊爆浆的老照片 1 s 内变成清晰、高清的有色照片。 而以上这些效果,无需专业 PS 技能,只用一个网页端的 Demo、点点鼠标上传图片就能搞定。 这个修复神器,由腾讯 PCG ARC 实验室研发&#xf…

结构体大揭秘:代码中的时尚之选(上)

目录 结构结构的声明结构成员的类型结构体变量的定义和初始化结构体成员的访问结构体传参 结构 结构是一些值的集合,这些值被称为成员变量。之前说过数组是相同类型元素的集合。结构的每个成员可以是不同类型的变量,当然也可以是相同类型的。 我们在生活…

【系统调用IO】open、close、read、write、lseek

目录 3 系统调用IO3.1 文件描述符3.1.1 FILE结构体3.2.2 文件描述符 3.3 open、close、read、write、lseek3.3.1 文件权限3.3.2 open3.3.3 close3.3.4 read3.3.5 write3.3.6 lseek3.3.7 代码示例 文件io和标准io的区别 橙色 3 系统调用IO 3.1 文件描述符 3.1.1 FILE结构体 …

多线程编程1

一、线程的引入 上节,我们介绍了进程的概念,以及操作系统内核是如何管理进程的(描述组织),PCB中的核心属性有哪些, 引入进程这个概念,最主要的目的,就是为了解决“并发编程”这样的…

JavaScript语法摘要

JavaScript语法摘要 JavaScript语法通过各种规则和组合,就能创建出丰富多彩的程序呢!它包括了怎么声明和使用变量、如何定义和赋值,还有怎么用运算符和表达式等等。另外,我还发现了一些有趣的概念,比如关键字、注释、…

Python学习从0到1 day7 Python判断语句

路远殊途,祝你得偿所愿 ——24.1.21 前言 进行逻辑判断,是生活中常见的行为,同样,在程序中,进行逻辑判断也是最为基础的功能 一、布尔类型和比较运算符 1.布尔类型 进行判断,有两个结果,True、…

springboot集成COS对象存储

1.申请腾讯云存储桶 新建密钥(后面配置要用到) 2.编写工具类 此处使用工具类进行基本属性配置,也可选择在yml中配置 package com.sfy.util;import com.qcloud.cos.COSClient; import com.qcloud.cos.ClientConfig; import com.qcloud.cos.a…

基于xgboost-LGBM-SVM的病人哮喘病识别检测 数据+代码

基于xgboost-LGBM-SVM的病人哮喘病识别检测-完整代码可直接运行_哔哩哔哩_bilibili 代码: from sklearn import preprocessing import random from sklearn.model_selection import train_test_split from sklearn.preprocessing import MinMaxScaler from sklearn import pr…

声明式注解对XXL-JOB的定时任务代码生效吗?

说明:源于博主的思考,本文验证一下声明式注解,即Transactional注解,对XXL-JOB的定时任务是否生效。 准备 首先,创建一个需要事务的场景。有两张表,一张部门表,一张用户表,用户隶属…

基于YOLOv8的目标识别、计数、电子围栏的项目开发过程

0 前言 用于生产环境中物体检测、识别、跟踪,人、车流量统计,越界安全识别 1 YOLOv8概述 YOLOv8 是Ultralytics的YOLO的最新版本。作为一种前沿、最先进(SOTA)的模型,YOLOv8在之前版本的成功基础上引入了新功能和改进,以提高性…

cupy,一个超级实用的 Python 库!

更多资料获取 📚 个人网站:ipengtao.com 大家好,今天为大家分享一个超级实用的 Python 库 - cupy。 Github地址:https://github.com/cupy/cupy 深度学习和科学计算需要处理大规模的数据和复杂的计算任务,而Python是一…

tag 标签

tag 标签 在使用 Git 版本控制的过程中,会产生大量的版本。如果我们想对某些重要版本进行记录,就可以给仓库历史中的某一个commit 打上标签,用于标识。 在本章中,我们将会学习如何列出已有的标签、如何创建和删除新的标签、以及…

20240116使用Firefly的AIO-3399J的预编译的Android10固件确认RT5640声卡信息

20240116使用Firefly的AIO-3399J的预编译的Android10固件确认RT5640声卡信息 2024/1/16 17:55 百度:RK3399 ALC5640 RK3399 RT5640 BING:RK3399 ALC5640 LINE-IN接麦克风不会有声音的。 耳机只有右边有声音,但是偏小,可以通过音量…

C++ memmove 学习

memmove&#xff0c;将num字节的值从源指向的位置复制到目标指向的内存块。 允许目标和源有重叠。 当目标区域与源区域没有重叠则和memcpy函数功能相同。 宽字符版本是wmemmove&#xff0c;安全版本加_s&#xff1b; #include "stdafx.h" #include<iostream&g…

如何为不同品牌的笔记本电脑设置充电限制,这里提供详细步骤

笔记本电脑的电池健康状况至关重要。延长电池寿命可以帮你省下不少钱。对于长时间充电的Windows 11笔记本电脑用户来说,将电池电量限制在80%是很重要的。 虽然操作系统没有提供设置自定义电池充电限制的内置方法,但仍有一些方法可以在Windows 11中配置电池设置,并将其限制在…