当前位置: 首页 > news >正文

大语言模型推理提速:TensorRT-LLM 高性能推理实践

作者:顾静

TensorRT-LLM 如何提升 LLM 模型推理效率

大型语言模型(Large language models,LLM)是基于大量数据进行预训练的超大型深度学习模型。底层转换器是一组神经网络,这些神经网络由具有 self-attention 的编码器和解码器组成。编码器和解码器从一系列文本中提取含义,并理解其中的单词和短语之间的关系。

当前 LLM 模型推理的主要瓶颈是 GPU 显存资源不足。因此,各类加速框架主要集中于降低 GPU 显存峰值提高 GPU 使用率两大目标。

TensorRT-LLM [ 1] 是 NVIDIA 推出的大语言模型(LLM)推理优化框架。它提供了一组 Python API 用于定义 LLMs,并且使用最新的优化技术将 LLM 模型转换为 TensorRT Engines,推理时直接使用优化后的 TensorRT Engines。

TensorRT-LLM 主要利用以下四项优化技术提升 LLM 模型推理效率。

1. 量化

模型量化技术是通过降低原始模型的精度来减少模型推理时的 GPU 显存使用。TensorRT 支持多种模型的多种精度,以下列举了部分主流模型支持的量化精度。

图片

W8A8 SQ 使用了 SmoothQuant 技术 [ 2] ,在不降低模型推理准确率的前提下,将模型权重和激活层都降低为 INT8 精度,显著减少了 GPU 显存消耗。

W4A16/W8A16 是指模型权重为 INT4 或者 INT8,激活层为 FP16 精度。

W4A16 AWQ 以及 W4A16 GPTQ 分别实现了 AWQ [ 3] 和 GPTQ [ 4] 两篇论文中提到的量化方法。模型权重为 INT4,激活层为 FP16 精度。

2. In-Flight Batching

传统的 Batching 技术为 Static Batching 的,需要等 Batching 中所有序列推理完成后才能进行下一次批次。下图为一个输出最大 Token 为 8,Batch size 为 4 的推理过程,使用 Static Batching 技术。S3 序列在 T5 时刻就已经完成推理,但是需要等到 S2 序列在 T8 时刻推理完成后才会处理下一个 sequence,存在明显的资源浪费。

图片

In-Flight Batching 又名 Continuous Batching 或 iteration-level batching,该技术可以提升推理吞吐率,降低推理时延。Continuous Batching 处理过程如下,当 S3 序列处理完成后插入一个新序列 S5 进行处理,提升资源利用率。详情可参考论文 Orca: A Distributed Serving System for Transformer-Based Generative Models [ 5]

图片

3. Attention

Attention 机制用于从序列中提取关键/重要信息,在情感识别、翻译、问答等任务中起着至关重要的作用。Attention 机制按照演进顺序可以分为 MHA(Multi-head Attention)、MQA(Multi-query Attention) [ 6] 以及 GQA(Group-query Attention) [ 7] 机制。MQA 和 GQA 都是 MHA 的变种。

图片

MHA 是标准的多头注意力机制,每个 query 存储一份 KV,因此需要使用较多的显存。MQA 所有 query 共享一份 KV,推理时容易丢失一些细节信息。GQA 将 query 进行分组,组内共享一份 KV,可以有效避免 MHA 和 MQA 的问题。

TensorRT-LLM 支持 MHA、MQA 及 GQA 方式,可以在 tensorrt_llm.functional.gpt_attention 查看具体实现。

4. Graph Rewriting

TensorRT-LLM 在将 LLM 模型编译为 TensorRT Engines 时会对神经网络进行优化,提升执行效率。

基于阿里云容器服务 ACK 的实战体验

云原生 AI 套件

云原生 AI 套件是阿里云容器服务 ACK 提供的云原生 AI 技术和产品方案,帮助企业更快、更高效地落地云原生 AI 系统。

本文将介绍如何基于阿里云容器服务 ACK 云原生 AI 套件,利用 TensorRT-LLM 优化 LLM 模型推理。

环境配置

  1. 参考文档安装云原生 AI 套件 [ 8]

  2. 登陆容器服务管理控制台 [ 9] ,在左侧导航栏选择集群 > 应用 > 云原生 AI 套件。等待开发控制台准备就绪后,单击开发控制台

  3. 开发控制台左侧,选择 Notebook,在 Notebook 页面右上角,单击创建 Notebook 创建新的 Notebook 环境。Notebook 资源需要 CPU:12C,内存:40G,GPU 显存:24GB。(节点对应规格为 ecs.gn7i-c16g1.4xlarge [ 10] )

图片

准备 TensorRT-LLM 环境

  1. 构建 Notebook 所需镜像。
FROM docker.io/nvidia/cuda:12.2.2-cudnn8-runtime-ubuntu22.04ENV DEBIAN_FRONTEND=noninteractiveRUN apt-get update && apt-get upgrade -y && \apt-get install -y --no-install-recommends \libgl1 libglib2.0-0 wget git curl vim \python3.10 python3-pip python3-dev build-essential \openmpi-bin libopenmpi-dev jupyter-notebook jupyterRUN pip3 install tensorrt_llm -U --extra-index-url https://pypi.nvidia.com
RUN pip3 install --upgrade jinja2==3.0.3 pynvml>=11.5.0RUN rm -rf /var/cache/apt/ && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \rm -rf /root/.cache/pip/ && rm -rf /*.whlWORKDIR /root
RUN git clone https://github.com/NVIDIA/TensorRT-LLM.git --branch v0.7.1ENTRYPOINT ["sh","-c","jupyter notebook --allow-root --notebook-dir=/root --port=8888 --ip=0.0.0.0 --ServerApp.token=''"]
  1. 下载模型,本文以 Baichuan2-7B-Base 为例。

a.确认 tensorrt_llm 安装成功

! python3 -c "import tensorrt_llm; print(tensorrt_llm.__version__)"
# 0.7.1

b.安装 baichuan 依赖

! cd /root/TensorRT-LLM/examples/baichuan
!pip3 install -r requirements.txt

c.下载 Baichuan2-7B-Chat 模型

!yum install git-lfs
!GIT_LFS_SKIP_SMUDGE=1 git clone https://www.modelscope.cn/baichuan-inc/Baichuan2-7B-Chat.git
!cd Baichuan2-7B-Chat/
!git lfs pull

d.将模型编译为 TensorRT Engines,权重指定为 INT8。模型转换约 5 分钟。

! cd /root/TensorRT-LLM/examples/baichuan
# Build the Baichuan V2 7B model using a single GPU and apply INT8 weight-only quantization.
! python3 build.py --model_version v2_7b \--model_dir ./Baichuan2-7B-Chat \--dtype float16 \--use_gemm_plugin float16 \--use_gpt_attention_plugin float16 \--use_weight_only \--output_dir ./tmp/baichuan_v2_7b/trt_engines/int8_weight_only/1-gpu/

e.使用构建好的 tensort engines 进行推理

# With INT8 weight-only quantization inference
! python3 ../run.py --input_text "世界上第二高的山峰是哪座?" \--max_output_len=50 \--tokenizer_dir=./Baichuan2-7B-Chat \--engine_dir=./tmp/baichuan_v2_7b/trt_engines/int8_weight_only/1-gpu/

预期输出:

Input [Text 0]: "世界上第二高的山峰是哪座?"
Output [Text 0 Beam 0]: "世界上第二高的山峰是喀喇昆仑山脉的乔戈里峰(K2),海拔高度为8611米。"

性能测试

  1. 使用 TensorRT-LLM 自带的 benchmark。

向 _allowed_configs dict 中添加 baichuan2_7b_chat 配置,代码可参考链接 [1****1]

🔔 注:0.7.1 版本 benchmark 还未支持 baichuan2 模型,因此需要手动修改下 allowed_configs 配置。

! cd /root/TensorRT-LLM/benchmarks/python
! vim allowed_configs.py
#   "baichuan2_7b_chat":ModelConfig(name="baichuan2_7b_chat",family="baichuan_7b",benchmark_type="gpt",build_config=BuildConfig(num_layers=32,num_heads=32,hidden_size=4096,vocab_size=125696,hidden_act='silu',n_positions=4096,inter_size=11008,max_batch_size=128,max_input_len=512,max_output_len=200,builder_opt=None,)),

运行 benchmark:

! python3 benchmark.py \-m baichuan2_7b_chat \--mode plugin \--engine_dir /root/TensorRT-LLM/examples/baichuan/tmp/baichuan_v2_7b/trt_engines/int8_weight_only/1-gpu \--batch_size 1 \--input_output_len "32,50;128,50"
# batch_size 并发度
# input_output_len 输入输出的长度,多个测试用例用分号分隔

Expected outputs:

[BENCHMARK] model_name baichuan2_7b_chat world_size 1 num_heads 32 num_kv_heads 32 num_layers 32 hidden_size 4096 vocab_size 125696 precision float16 batch_size 1 input_length 32 output_length 50 gpu_peak_mem(gb) 8.682 build_time(s) 0 tokens_per_sec 60.95 percentile95(ms) 821.977 percentile99(ms) 822.093 latency(ms) 820.348 compute_cap sm86 generation_time(ms) 798.45 total_generated_tokens 49.0 generation_tokens_per_second 61.369
[BENCHMARK] model_name baichuan2_7b_chat world_size 1 num_heads 32 num_kv_heads 32 num_layers 32 hidden_size 4096 vocab_size 125696 precision float16 batch_size 1 input_length 128 output_length 50 gpu_peak_mem(gb) 8.721 build_time(s) 0 tokens_per_sec 59.53 percentile95(ms) 841.708 percentile99(ms) 842.755 latency(ms) 839.852 compute_cap sm86 generation_time(ms) 806.571 total_generated_tokens 49.0 generation_tokens_per_second 60.751
  1. 对比 INT8 量化模型与原始模型性能。

原始模型执行命令:

def normal_inference():from transformers import AutoModelForCausalLM, AutoTokenizerfrom transformers.generation.utils import GenerationConfigtokenizer = AutoTokenizer.from_pretrained(model_path, use_fast=False, trust_remote_code=True)model = AutoModelForCausalLM.from_pretrained(model_path, device_map="auto", torch_dtype=torch.bfloat16, trust_remote_code=True)model.generation_config = GenerationConfig.from_pretrained(model_path)messages = []messages.append({"role": "user", "content": prompt})response = model.chat(tokenizer, messages)print(response)

INT8 量化模型命令:

def tensorrt_llm_inference():from subprocess import Popen, PIPEscript = f'''python3 /root/TensorRT-LLM/examples/run.py --input_text \"{prompt}\"  \--max_output_len=50 \--tokenizer_dir=/root/TensorRT-LLM/examples/baichuan/Baichuan2-7B-Chat \--engine_dir=/root/TensorRT-LLM/examples/baichuan/tmp/baichuan_v2_7b/trt_engines/int8_weight_only/1-gpu/'''p = Popen(['sh', '-c', script], stdout=PIPE,stderr=PIPE)output, err = p.communicate()if p.returncode != 0:print(f"tensorrt_llm_inference() error:{err}")returnprint(output)

图片

TensorRT-LLM 加速方案在采用 INT8 模型量化的情况下,相比于默认的 Baichuan2-7B-Chat 模型,显存峰值降低了 *43.8% *,时延降低了 61.1%。

参考文献:

https://nvidia.github.io/TensorRT-LLM/architecture.html

https://www.anyscale.com/blog/continuous-batching-llm-inference

相关链接:

[1] TensorRT-LLM

https://github.com/NVIDIA/TensorRT-LLM

[2] SmoothQuant技术

https://arxiv.org/abs/2211.10438

[3] AWQ

https://arxiv.org/abs/2306.00978

[4] GPTQ

https://arxiv.org/abs/2210.17323

[5] Orca: A Distributed Serving System for Transformer-Based Generative Models

https://help.aliyun.com/zh/eventbridge/user-guide/transform/?spm=a2c4g.11186623.0.0.501b5750w5RP1Q

[6] MQA(Multi-query Attention)

https://arxiv.org/abs/1911.02150

[7] GQA(Group-query Attention)

https://arxiv.org/abs/2307.09288

[8] 安装云原生AI套件

https://help.aliyun.com/zh/ack/cloud-native-ai-suite/user-guide/deploy-the-cloud-native-ai-suite?spm=a2c4g.11186623.0.0.7e223d92U1aVNf

[9] 容器服务管理控制台

https://account.aliyun.com/login/login.htm?oauth_callback=https%3A%2F%2Fcs.console.aliyun.com%2F

[10] ecs.gn7i-c16g1.4xlarge

https://help.aliyun.com/zh/ecs/user-guide/overview-of-instance-families#gn7i

[11] 链接

https://github.com/NVIDIA/TensorRT-LLM/blob/12e82e30b0e64b0f7ada0dc5993edd3b05385964/benchmarks/python/allowed_configs.py#L940

相关文章:

大语言模型推理提速:TensorRT-LLM 高性能推理实践

作者:顾静 TensorRT-LLM 如何提升 LLM 模型推理效率 大型语言模型(Large language models,LLM)是基于大量数据进行预训练的超大型深度学习模型。底层转换器是一组神经网络,这些神经网络由具有 self-attention 的编码器和解码器组…...

全面理解“张量”概念

1. 多重视角看“张量” 张量(Tensor)是一个多维数组的概念,在不同的学科领域中有不同的应用和解释: 物理学中的张量: 在物理学中,张量是一个几何对象,用来表示在不同坐标系下变换具有特定规律的…...

MacOS X 安装免费的 LaTex 环境

最近把工作终端一步步迁移到Mac上来了,搭了个 Latex的环境,跟windows上一样好用。 首先,如果是 intel 芯片的 macOS,那么可以使用组合1, 如果是 M1、M2 或 M3 芯片或者 intel 芯片的 Mac book,则应该使用…...

深入Amazon S3:实战指南

Amazon S3(Simple Storage Service)是AWS(Amazon Web Services)提供的一项强大的云存储服务,广泛用于存储和检索各种类型的数据。本篇实战指南将深入介绍如何在实际项目中充分利用Amazon S3的功能,包括存储桶的创建、对象的管理、权限控制、版本控制、日志记录等方面的实…...

Ansible自动化运维(三)Playbook 模式详解

👨‍🎓博主简介 🏅云计算领域优质创作者   🏅华为云开发者社区专家博主   🏅阿里云开发者社区专家博主 💊交流社区:运维交流社区 欢迎大家的加入! 🐋 希望大家多多支…...

LCS板子加逆向搜索

LCS 题面翻译 题目描述: 给定一个字符串 s s s 和一个字符串 t t t ,输出 s s s 和 t t t 的最长公共子序列。 输入格式: 两行,第一行输入 s s s ,第二行输入 t t t 。 输出格式: 输出 s s s…...

不同知识表示方法与知识图谱

目录 前言1 一阶谓词逻辑1.1 简介1.2 优势1.3 局限性 2 产生式规则2.1 简介2.2 优势2.3 局限性 3 框架系统3.1 简介3.2 优势3.3 局限性 4 描述逻辑4.1 简介4.2 优势4.3 局限性 5 语义网络5.1 简介5.2 优势5.3 局限性 结语 前言 知识表示是人工智能领域中至关重要的一环&#x…...

Kotlin程序设计 扩展篇(一)

Kotlin程序设计(扩展一) **注意:**开启本视频学习前,需要先完成以下内容的学习: 请先完成《Kotlin程序设计》视频教程。请先完成《JavaSE》视频教程。 Kotlin在设计时考虑到了与Java的互操作性,现有的Ja…...

星环科技基于第五代英特尔®至强®可扩展处理器的分布式向量数据库解决方案重磅发布

12月15日,2023 英特尔新品发布会暨 AI 技术创新派对上,星环科技基于第五代英特尔至强可扩展处理器的Transwarp Hippo分布式向量数据库解决方案重磅发布。该方案利用第五代英特尔至强可扩展处理器带来的强大算力,实现了约 2 倍的代际性能提升&…...

一体化运维的发展趋势与未来展望

随着信息技术的迅猛发展,企业的IT系统已经从单一的、孤立的应用转变为多元化、复杂化的系统集群。云计算、大数据、物联网等前沿技术的广泛应用,使得企业的IT运维面临着前所未有的挑战。在这样的背景下,一体化运维作为一种新型的运维模式&…...

科技云报道:金融大模型落地,还需跨越几重山?

科技云报道原创。 时至今日,大模型的狂欢盛宴仍在持续,而金融行业得益于数据密集且有强劲的数字化基础,从一众场景中脱颖而出。 越来越多的公司开始布局金融行业大模型,无论是乐信、奇富科技、度小满、蚂蚁这样的金融科技公司&a…...

C语言入门到精通之练习34:求100之内的素数

题目&#xff1a;求100之内的素数。 程序分析&#xff1a;质数&#xff08;素数&#xff09;酵母素数&#xff0c;有无限个。一个大于1的自然数&#xff0c;除了1和它本身外&#xff0c;不能被其他自然数整除。 代码如下&#xff1a; #include <stdio.h># #include &l…...

Qt采集本地摄像头推流成rtsp/rtmp(可网页播放/支持嵌入式linux)

一、功能特点 支持各种本地视频文件和网络视频文件。支持各种网络视频流&#xff0c;网络摄像头&#xff0c;协议包括rtsp、rtmp、http。支持将本地摄像头设备推流&#xff0c;可指定分辨率和帧率等。支持将本地桌面推流&#xff0c;可指定屏幕区域和帧率等。自动启动流媒体服…...

Oracle按日周月年自动分区

目录 1、分区键 2、初始分区 3、周月年自动分区 4、按日自动分区表建表语句 与普通建表语句相比&#xff0c;分区表多了一些分区信息&#xff1b; 1、分区键 以下面销售明细表为例&#xff0c;以data_dt为分区键&#xff0c;NUMTODSINTERVAL(1, day) 按日分区 PARTITION …...

单元测试、模块测试、web接口测试

单元测试与模块测试 什么是“单元测试”、“模块测试”&#xff1f; 然而在功能的实现代码中并没有“单元”&#xff0c;也没有“模块”&#xff1b;只有函数、类和方法。先来分别看看它们 的定义&#xff1a; 单元测试&#xff08;Unit testing&#xff09;&#xff0c;是指…...

DAY10_SpringBoot—SpringMVC重定向和转发RestFul风格JSON格式SSM框架整合Ajax-JQuery

目录 1 SpringMVC1.1 重定向和转发1.1.1 转发1.1.2 重定向1.1.3 转发练习1.1.4 重定向练习1.1.5 重定向/转发特点1.1.6 重定向/转发意义 1.2 RestFul风格1.2.1 RestFul入门案例1.2.2 简化业务调用 1.3 JSON1.3.1 JSON介绍1.3.2 JSON格式1.3.2.1 Object格式1.3.2.2 Array格式1.3…...

刘润-进化的力量2 一刷 笔记

安全感来自确定性&#xff0c;但机会藏在不确定性中 安全感来自确定性&#xff0c;但机会藏在不确定性中。 每一个弯道里&#xff0c;都有你超车的机会 意外、周期、趋势、规划 可是&#xff0c;为什么趋势一定是不可逆转的呢&#xff1f;因为&#xff0c;效率提高了 长期…...

用Excel辅助做数独

做数独游戏的时候&#xff0c;画在纸上很容易弄花眼&#xff0c;所以我考虑用Excel辅助做一个。 界面如下&#xff1a; 按下初始化表格区域按钮&#xff0c;会在所有单元格中填充“123456789”。如下图&#xff1a; 当某个单元格删除得只剩一个数字时&#xff0c;会将同一行、…...

arcgis实现截图/截屏功能

arcgis实现截图/截屏功能 文章目录 arcgis实现截图/截屏功能前言效果展示相关代码 前言 本篇将使用arcgis实现截图/截屏功能&#xff0c;类似于qq截图 效果展示 相关代码 <!DOCTYPE html> <html> <head><meta charset"utf-8"><meta nam…...

mysql备份

1.新建备份目录 mkdir -p /data/mysql_dump/#查找mysql配置位置 find / -name "my.cnf" find / -name "mysql.sock" find / -name "mysqldump"2.定时任务 #每天凌晨备份一次 echo "00 00 * * * root /data/mysql_bak.sh" >> /…...

CentOS7 安装PostgreSQL以及配置服务

文章目录 前言1. 安装步骤2. 连接PostgreSQL3. 配置服务配置文件所在路径设置监听地址修改数据库密码已经修改了密码,为什么没有生效?不需要密码就可以连接?设置访问权限4. 新的配置生效前言 PostgreSQL是一种功能强大的开源关系型数据库管理系统,被广泛用于各种应用程序和…...

React 表单、处理受控表单组件、非受控组件

React 表单处理 学习目标&#xff1a; 能够使用受控组件的方式获取文本框 使用 React 处理表单一般有两种方法 受控组件 &#xff08;推荐&#xff09;非受控组件 &#xff08;了解&#xff09; 1. 受控表单组件 什么是受控组件&#xff1f; input 框自己的状态被 React 组…...

Android开发--状态栏布局隐藏的方法

1.问题如下&#xff0c;安卓布局很不协调 2.先将ActionBar设置为NoActionBar 先打开styles.xml 3.使用工具类 package com.afison.newfault.utils;import android.annotation.TargetApi; import android.app.Activity; import android.content.Context; import android.graph…...

GaussDB如何创建和管理序列、定时任务

前言 GaussDB是华为自主创新研发的分布式关系型数据库&#xff0c;为企业提供功能全面、稳定可靠、扩展性强、性能优越的企业级数据库服务。在实际业务场景使用中&#xff0c;为了提高工作效率&#xff0c;数据库GaussDB提供定时任务的功能&#xff0c;本节为大家讲解GaussDB如…...

mybatis-plus:代码生成器

一、依赖 代码生成器需要添加一下依赖 <dependencies><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.0.7.1</version></dependency><!-- https://mvnre…...

几款提高开发效率的Idea 插件

1、ignore 开发代码过程中经常会有一些需要提交到代码仓库的文件&#xff0c;比如java文件生成的.class、.jar 等&#xff0c;如果将编译后的文件都提交到代码库那么代码库会很大&#xff0c;关键是没有必要。 这款插件就可以很方便的解决某类文件或者某个文件夹不需要提交到…...

Redisson 分布式锁可重入的原理

目录 1. 使用 Redis 实现分布式锁存在的问题 2. Redisson 的分布式锁解决不可重入问题的原理 1. 使用 Redis 实现分布式锁存在的问题 不可重入&#xff1a;同一个线程无法两次 / 多次获取锁举例 method1 执行需要获取锁method2 执行也需要&#xff08;同一把&#xff09;锁如…...

【Vue实用功能】Vue实现文档在线预览功能,在线预览PDF、Word等office文件

1、Office Web(微软的开发接口) 优点 没有 Office也可以直接查看Office 文件适用于移动端、PC无需下载文件就可以在浏览器中查看 <iframe src"文档地址" frameborder"0" /> const docUrl 外网可预览的地址 const url encodeURIComponent(docUrl…...

【一站解决您的问题】mac 利用命令升级nodejs、npm、安装Nodejs的多版本管理器n、nodejs下载地址

一&#xff1a;下载nodejs 官网地址&#xff0c;点击下载稳定版 https://nodejs.org/en 如果官网下载特别慢&#xff0c;可以点击这个地址下载 点击这里 https://nodejs.cn/download/current/ 安装完成后&#xff0c;就包含了nodejs 和 npm。此时您的版本就是下载安装的版本…...

【RabbitMQ】死信(延迟队列)的使用

目录 一、介绍 1、什么是死信队列(延迟队列) 2、应用场景 3、死信队列(延迟队列)的使用 4、死信消息来源 二、案例实践 1、案例一 2、案例二&#xff08;消息接收确认 &#xff09; 3、总结 一、介绍 1、什么是死信队列(延迟队列) 死信&#xff0c;在官网中对应的单词…...

金融网站建设方案/网络媒体有哪些

WMS是仓库管理系统(Warehouse Management System) 的缩写&#xff0c;仓库管理系统是通过入库业务、出库业务、仓库调拨、库存调拨和虚仓管理等功能&#xff0c;综合批次管理、物料对应、库存盘点、质检管理、虚仓管理和即时库存管理等功能综合运用的管理系统&#xff0c;有效控…...

wordpress博客栏目设计/小学生关键词大全

1、分布式&#xff1a;一个业务分拆多个子业务&#xff0c;部署在不同的服务器上。 2、集群&#xff1a;同一个业务&#xff0c;部署在多个服务器上。 3、集群是解决高可用的&#xff0c;而分布式是解决高性能、高并发的。 4、集群是个物理形态&#xff0c;分布式是个工作方…...

门户网站的注意要素/排名优化怎么做

第一章 基础知识 1.1 对称算法 对称算法使用一个密钥。给定一个明文和一个密钥&#xff0c;加密产生密文&#xff0c;其长度和明文大致相同。解密时&#xff0c;使用读密钥与加密密钥相同。 对称算法主要有四种加密模式&#xff1a; (1) 电子密码本模式 Electronic Code Bo…...

设计b2c网站建设/seo最强

其实很简单&#xff0c;一般的数组去重可以直接用 new Set() 方法即可&#xff0c;但是数组对象的话&#xff0c;比较复杂&#xff0c;不能直接用&#xff0c;我们可以采取间接的方法来去重unique(arr) {const res new Map();return arr.filter((arr) > !res.has(arr.id) &…...

wordpress tag云显示数量/seo技巧分享

2012-6~2013-9 在思科中国合肥研发中心实习 2014-5-6 正式步入职场目前就职于一家互联网公司平时喜欢将工作中学习中体会到的一些东西写出来&#xff0c;分享给大家&#xff0c;互联网就是一个分享的平台&#xff0c;共同分享&#xff0c;共同学习&#xff0c;共同进步&#x…...

wordpress po翻译/网站建设制作免费

目标 需要处理的数据 成果 思路&#xff1a;第一步.先把嵌套文档&#xff08;对象&#xff09;转换为数组 知识点&#xff1a;$ objectToArray与$ ArrayToobject db.exception.aggregate([{$project:{_id:1,name:1,pointName:1,enterpriseName:1,mn:1,busId:1,dataType:1,&quo…...