Resnet C ++ 部署 tensort 部署(四)
Resnet C ++ 部署 pytorch功能测试(一)
Resnet C ++ 部署 模型训练(二)
Resnet C ++ 部署 模型测试&转 onnx(三)
Resnet C ++ 部署 tensort 部署(四)
之后,开始onnx 转trt 部署测试
1 代码
这是核心代码,改一下main 函数里面的参数,推理函数里面的参数即可运行
#include "NvInfer.h"
#include "cuda_runtime_api.h"
#include <fstream>
#include <iostream>
#include <map>
#include <sstream>
#include <vector>
#include <chrono>
#include <cmath>
#include <cassert>
#include<Windows.h>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
// onnx转换头文件
#include "NvOnnxParser.h"
#include"read_config.hpp"
#include"labels.hpp"
#include "NvInferPlugin.h"
using namespace nvonnxparser;using namespace std;#define CHECK(status) \do\{\auto ret = (status);\if (ret != 0)\{\std::cerr << "Cuda failure: " << ret << std::endl;\abort();\}\} while (0)// stuff we know about the network and the input/output blobs
static const int INPUT_H = 224;
static const int INPUT_W = 224;
static const int OUTPUT_SIZE = 2;const char* INPUT_BLOB_NAME = "images";
const char* OUTPUT_BLOB_NAME = "prob";
void* global_buffers[2];using namespace nvinfer1;//static Logger gLogger;//构建Logger
class Logger : public ILogger
{void log(Severity severity, const char* msg) noexcept override{// suppress info-level messagesif (severity <= Severity::kWARNING)std::cout << msg << std::endl;}
} gLogger;// Creat the engine using only the API and not any parser.
ICudaEngine* createEngine(unsigned int maxBatchSize, IBuilder* builder, IBuilderConfig* config,string onnx_name)
{int dir_l = 0;int dir_r = onnx_name.rfind(".");string enginePath;onnx_name = onnx_name.substr(dir_l, dir_r)+".onnx";std::cout << "onnx_name:" << onnx_name << std::endl;const char* onnx_path = onnx_name.c_str();INetworkDefinition* network = builder->createNetworkV2(1U); //此处重点1U为OU就有问题IParser* parser = createParser(*network, gLogger);parser->parseFromFile(onnx_path, static_cast<int32_t>(ILogger::Severity::kWARNING));for (int32_t i = 0; i < parser->getNbErrors(); ++i) { std::cout << parser->getError(i)->desc() << std::endl; }std::cout << "successfully load the onnx model" << std::endl;// Build enginebuilder->setMaxBatchSize(maxBatchSize);builder->setMaxBatchSize(maxBatchSize);config->setMaxWorkspaceSize(1 << 20);config->setFlag(nvinfer1::BuilderFlag::kFP16); // 设置精度计算//config->setFlag(nvinfer1::BuilderFlag::kINT8);ICudaEngine* engine = builder->buildEngineWithConfig(*network, *config);std::cout << "successfully create engine " << std::endl;//销毁network->destroy();parser->destroy();return engine;
}void APIToModel(unsigned int maxBatchSize, IHostMemory** modelStream, string trt_name)
{// Create builderIBuilder* builder = createInferBuilder(gLogger);IBuilderConfig* config = builder->createBuilderConfig();std::cout << "trt_name:" << trt_name << std::endl;// Create model to populate the network, then set the outputs and create an engineICudaEngine* engine = createEngine(maxBatchSize, builder, config, trt_name);assert(engine != nullptr);// Serialize the engine(*modelStream) = engine->serialize();// Close everything downengine->destroy();builder->destroy();config->destroy();
}void do_Initial(int batchSize)
{//void* buffers[2];//buffers[0] = global_buffers[0];//buffers[1] = global_buffers[1];// Pointers to input and output device buffers to pass to engine.// Engine requires exactly IEngine::getNbBindings() number of buffers.// float* m_bindings[2];// In order to bind the buffers, we need to know the names of the input and output tensors.// Note that indices are guaranteed to be less than IEngine::getNbBindings()const int inputIndex = 0; //inputIndex = 0const int outputIndex = 1;//outputIndex = 1// Create GPU buffers on deviceCHECK(cudaMalloc(&global_buffers[inputIndex], batchSize * 3 * INPUT_H * INPUT_W * sizeof(float)));CHECK(cudaMalloc(&global_buffers[outputIndex], batchSize * OUTPUT_SIZE * sizeof(float)));// Release stream and buffers
}
void do_Inference(IExecutionContext *context_,float* input, float* output, int batchSize,cudaStream_t &stream)
{const int inputIndex = 0; //inputIndex = 0const int outputIndex = 1;//outputIndex = 1//void* buffers[2];//buffers[0] = global_buffers[0];//buffers[1] = global_buffers[1]; Create GPU buffers on device//CHECK(cudaMalloc(&buffers[inputIndex], batchSize * 3 * INPUT_H * INPUT_W * sizeof(float)));//CHECK(cudaMalloc(&buffers[outputIndex], batchSize * OUTPUT_SIZE * sizeof(float)));// Create streamCHECK(cudaStreamCreate(&stream));// DMA input batch data to device, infer on the batch asynchronously, and DMA output back to hostCHECK(cudaMemcpyAsync(global_buffers[inputIndex], input, batchSize * 3 * INPUT_H * INPUT_W * sizeof(float), cudaMemcpyHostToDevice, stream));context_->enqueueV2(global_buffers, stream, nullptr);//Changed by xfx20241202CHECK(cudaMemcpyAsync(output, global_buffers[outputIndex], batchSize * OUTPUT_SIZE * sizeof(float), cudaMemcpyDeviceToHost, stream));cudaStreamSynchronize(stream);
}void do_uninitial(cudaStream_t &stream, void* buffers[2])
{cudaStreamDestroy(stream);CHECK(cudaFree(buffers[0]));CHECK(cudaFree(buffers[1]));
}//加工图片变成拥有batch的输入, tensorrt输入需要的格式,为一个维度
void ProcessImage(vector<cv::Mat> images, float input_data[],const int batch_tem) {//只处理一张图片,总之结果为一维[batch*3*INPUT_W*INPUT_H]//以下代码为投机取巧了std::vector<cv::Mat> InputImage;if(images.size() != batch_tem){std::cout << "image batch is unequal to batch_tem" << std::endl;exit(-1);}for (int i = 0; i < batch_tem; ++i){cv::resize(images[i], images[i], cv::Size(INPUT_W, INPUT_H), 0, 0, cv::INTER_LINEAR);InputImage.push_back(images[i]);} int ImgCount = InputImage.size();//std::cout <<"ImgCount:" << ImgCount << std::endl;//float input_data[BatchSize * 3 * INPUT_H * INPUT_W];for (int b = 0; b < ImgCount; b++) {cv::Mat img = InputImage.at(b);int w = img.cols;int h = img.rows;int i = 0;for (int row = 0; row < h; ++row) {uchar* uc_pixel = img.data + row * img.step;for (int col = 0; col < INPUT_W; ++col) {input_data[b * 3 * INPUT_H * INPUT_W + i] = (float)uc_pixel[2] / 255.0;input_data[b * 3 * INPUT_H * INPUT_W + i + INPUT_H * INPUT_W] = (float)uc_pixel[1] / 255.0;input_data[b * 3 * INPUT_H * INPUT_W + i + 2 * INPUT_H * INPUT_W] = (float)uc_pixel[0] / 255.0;uc_pixel += 3;++i;}}}}int get_trtengine(string trt_name) {int dir_l = 0;int dir_r = trt_name.rfind(".");trt_name = trt_name.substr(dir_l, dir_r) + ".engine";IHostMemory* modelStream{ nullptr };APIToModel(100, &modelStream, trt_name);assert(modelStream != nullptr);std::ofstream p(trt_name, std::ios::binary);if (!p){std::cerr << "could not open plan output file" << std::endl;return -1;}p.write(reinterpret_cast<const char*>(modelStream->data()), modelStream->size());modelStream->destroy();return 0;}int infer(string trt_name, const int batch_tem_, int loop_time_) {int batch_tem = batch_tem_;int loop_time = loop_time_;int dir_l = 0;int dir_r = trt_name.rfind(".");trt_name = trt_name.substr(dir_l, dir_r) + ".engine";//加载engine引擎char* trtModelStream{ nullptr };size_t size{ 0 };std::ifstream file(trt_name, std::ios::binary);if (file.good()) {file.seekg(0, file.end);size = file.tellg();file.seekg(0, file.beg);trtModelStream = new char[size];assert(trtModelStream);file.read(trtModelStream, size);file.close();}//反序列为engine,创建contextIRuntime* runtime = createInferRuntime(gLogger);assert(runtime != nullptr);ICudaEngine* engine = runtime->deserializeCudaEngine(trtModelStream, size, nullptr);int32_t inputD = 0;// engine->getBindingDimensions(inputD).d[0]//auto engine->getBindingDimensions;assert(engine != nullptr);IExecutionContext* context = engine->createExecutionContext();assert(context != nullptr);delete[] trtModelStream;//*********************推理*********************//// 循环推理float time_read_img = 0.0;float time_infer = 0.0;float *prob = new float[batch_tem*OUTPUT_SIZE];float *data = new float[batch_tem * 3 * INPUT_H * INPUT_W];do_Initial(batch_tem);cudaStream_t stream;for (int loop = 0; loop < loop_time; loop++){// 处理图片为固定输出auto start = std::chrono::system_clock::now(); //时间函数 std::string path2 = "./data/cat.png";vector<cv::Mat> images;cv::Mat img2 = cv::imread(path2);//images.push_back(img);for (int i = images.size(); i < batch_tem; ++i){images.push_back(img2);}//--ProcessImage(images, data, batch_tem);auto end = std::chrono::system_clock::now();time_read_img = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() + time_read_img; start = std::chrono::system_clock::now(); //时间函数for (int i = 0; i < 1; ++i){do_Inference(context, data, prob, batch_tem, stream);}end = std::chrono::system_clock::now();time_infer = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() + time_infer;//std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms" << std::endl;//输出后处理//std::cout <<"prob="<<prob << std::endl;ImageNetLabels labels;for (int batch = 0; batch < batch_tem; ++batch){float cls_float = prob[0];int cls_id = 0;for (int i = (0+batch)* OUTPUT_SIZE; i < (1+batch)*OUTPUT_SIZE; i++){if (cls_float < prob[i]){cls_float = prob[i];cls_id = i;}printf("ID %d %f: %s\n", i% OUTPUT_SIZE, prob[i],labels.imagenet_labelstring(i%1000).c_str());}//printf("LOOP_time:%d batch: %d result %d \n", loop,batch, cls_id % 100);printf("Batch:%d ClassId:%d Class name:%s \n", batch, cls_id%OUTPUT_SIZE, labels.imagenet_labelstring(cls_id % 1000).c_str());}}do_uninitial(stream, global_buffers);std::cout << "C++ engine" << "mean read img time = " << time_read_img / loop_time << "ms\t" << "mean infer img time =" << time_infer / loop_time << "ms" << std::endl;// Destroy the enginecontext->destroy();engine->destroy();runtime->destroy();return 0;
}int main(int argc, char** argv)
{bool didInitPlugins = initLibNvInferPlugins(nullptr, "");string init_config_path = "./config/config.yaml";InitParameter m_init_para=yaml_read(init_config_path);std::cout <<"batch size:" << m_init_para.batch_size << std::endl;std::cout << "loop time:" << m_init_para.batch_size << std::endl;std::cout << "deylay time:" << m_init_para.delay_time << std::endl;std::cout << "model path:" << m_init_para.model_path << std::endl;std::cout << "mode:" << m_init_para.mode<<std::endl;// string mode = argv[1];string mode = m_init_para.mode; //适用windows编译,固定指定参数//if (std::string(argv[1]) == "-s") {if (mode == "-s") {std::cout << "m_init_para.model_path:" << m_init_para.model_path << std::endl;get_trtengine(m_init_para.model_path);}//else if (std::string(argv[1]) == "-d") {else if (mode == "-d") {infer(m_init_para.model_path, m_init_para.batch_size, m_init_para.loop_time);}else {return -1;}return 0;
}
2 精度比较
图片 | .pt | .onnx | .trt |
---|---|---|---|
cat | [1.0000e+00, 1.4013e-45] | [1.0000e+00, 1.4013e-45] | [0.999920,0.000080] |
3 结论
可以看出 onnx 模型精度损失很小 .trt 精度损失较大
相关文章:
Resnet C ++ 部署 tensort 部署(四)
Resnet C 部署 pytorch功能测试(一) Resnet C 部署 模型训练(二) Resnet C 部署 模型测试&转 onnx(三) Resnet C 部署 tensort 部署(四) 之后,开始onnx 转trt 部…...
《Java核心技术I》对并发散列映射的批操作
对并发散列映射的批操作 Java API提供了批处理,计时其他线程处理映射,这些操作也能安全的执行。 3种不同操作: search(搜索),为每个键或值应用一个函数,直到函数生成一个非null的结果,然后搜索终止&…...
记录一次使用git无权限的问题排查
正常的配置了公私钥之后,在gitlab中也存储了配对的公钥,但当使用git clone 时,总是报无权限 由于在这台机器中添加了多个公私钥,有点复杂,我们可以使用命令 ssh -vvvT 调试一下 ssh -vvvT yourGitlabAddr...
appium学习之二:adb命令
1、查看设备 adb devices 2、连接 adb connect IP:端口 3、安装 adb install xxx.apk 4、卸载 adb uninstall 【包名】 5、把对应目录下的1.txt文件传到手机sdcard下 adb push 1.txt /sdcard 6、进入对应的设备里 adb shell 7、切入sdcard目录 cd /sdcard 8、ls 查…...
Linux Vi/Vim使用 ⑥
掌握 CentOS 7 下的 Vi/Vim 编辑器:从安装到精通 在 CentOS 7 系统的日常运维、编程开发以及各类文本处理场景中,Vi/Vim 编辑器都是不可或缺的得力工具。它以轻量、高效、功能强大著称,虽然初次上手有一定学习门槛,但掌握之后便能…...
JCR一区牛顿-拉夫逊优化算法+分解对比!VMD-NRBO-Transformer-BiLSTM多变量时序光伏功率预测
JCR一区牛顿-拉夫逊优化算法分解对比!VMD-NRBO-Transformer-BiLSTM多变量时序光伏功率预测 目录 JCR一区牛顿-拉夫逊优化算法分解对比!VMD-NRBO-Transformer-BiLSTM多变量时序光伏功率预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.中科院…...
easyExcel实现表头批注
背景: 网上大部分都不能直接使用,为此总结一个方便入手且可用的工具,用自定义注解实现 依赖包: <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>…...
Pytest测试用例使用小结
基础使用 Pytest 测试用例实现代码 import pytest from server.service import Servicepytest.fixture def service():return Service(logger)class TestService:classmethoddef setup_class(cls):"""初始化设置一次:return:"""logger.info(&q…...
LeetCode题练习与总结:132 模式--456
一、题目描述 给你一个整数数组 nums ,数组中共有 n 个整数。132 模式的子序列 由三个整数 nums[i]、nums[j] 和 nums[k] 组成,并同时满足:i < j < k 和 nums[i] < nums[k] < nums[j] 。 如果 nums 中存在 132 模式的子序列 &a…...
IdentityServer4框架、ASP.NET core Identity
OAuth2.0 IdentityServer4 官网 中文官网 ASP.NET Core Identity提供了一个用来管理和存储用户账户的框架. IdentityServer4是基于ASP.NET Core实现的认证和授权框架,是对OpenID Connect和OAuth 2.0协议的实现。 IdentityServer是一个中间件,它可以添加符合OpenID…...
【分子材料发现】——GAP:催化过程中吸附构型的多模态语言和图学习(数据集处理详解)(二)
Multimodal Language and Graph Learning of Adsorption Configuration in Catalysis https://arxiv.org/abs/2401.07408Paper Data: https://doi.org/10.6084/m9.figshare.27208356.v2 1 Dataset CatBERTa训练的文本字符串输入来源于Open Catalyst 2020 (OC20…...
SpringBoot开发过程中经常遇到问题解决方案分享
目录 1. Spring Boot应用启动缓慢 2. 数据库连接池配置问题 3. Spring Boot应用无法连接外部服务 4. 配置文件读取不生效 5. Spring Boot应用的日志输出不完整 6. Spring Boot中的Transactional事务管理问题 1. Spring Boot应用启动缓慢 问题原因: Spring Boo…...
AR眼镜_消费级工业AR智能眼镜主板硬件解决方案
AR眼镜的研发是一项复杂的软硬件集成工程,它需要在摄影、音频、交互和连接等多个方面提供卓越的基础体验,因此产品的每个细节都显得尤为重要。 在设计AR眼镜时,重量、体积和散热性能都是必须认真考量的关键因素。在芯片平台的选择上ÿ…...
Springboot 核心注解
Spring Boot 是一个基于 Spring 框架的扩展,旨在简化新 Spring 应用的初始搭建以及开发过程。它通过自动配置和约定优于配置的原则,减少了开发者的工作量。Spring Boot 提供了一组核心注解和 Starter 依赖管理工具来帮助开发者快速启动项目。 1. Spring…...
Nacos集群搭建【Oracle作外部数据源】
一、知识点分析 1.Nocas是什么? Nacos是一个动态服务发现、配置管理和服务管理平台。 1.1定义与背景: Nacos,全称为Dynamic Naming and Configuration Service,是由阿里巴巴开源的云原生应用配套工具。它旨在简化微服务架…...
云轴科技ZStack出席中国电信国际EMCP平台香港发布会,持续推动海外合作
近日,以“云聚未来 翼起新篇”为主题的中国电信国际多云服务一站式平台(E-surfing Managed Cloud Platform,简称EMCP平台)新闻发布会在香港成功举办,标志着中国电信国际在云计算服务领域取得了又一重大进展。云轴科技…...
爬虫自动化之drissionpage+SwitchyOmega实现随时切换代理ip
本文介绍了如何使用DrizzlePage进行爬虫自动化,并重点讲解了首次启动时设置代理IP以及通过SwitchyOmega插件实现随时切换代理IP的方法。 安装一次,后面调用就不会再去安装了 下载地址:https://github.com/FelisCatus/SwitchyOmega/releases 这两个文件随便那个都可以,下载…...
docker安装kettle(PDI)并实现web访问
我是MAC电脑M1版本,希望把软件交给docker进行管理,最近公司同事都通过kettle来实现外部数据对接,所以我本地也有安装kettle需求,在网上找到了这个解决方案操作很简单,但出现了无法访问的情况。我的排查方式是ÿ…...
[软件工程]十.可靠性工程(reliable engineering)
1.什么是可靠性工程 我们希望软件在给定的时间内,运行的时候不会崩溃或者发生失效,同时能保护我们的数据和个人信息。我们要能够信任我们所使用的软件,这意味着软件必须是可靠的。可靠性(reliability):系统…...
【Makefile】编译日志之输出重定向符号 >
用法1 make all >& compilelog.txt make all > compilelog.txt这两个编译命令在功能上有一些细微的区别,主要在于标准输出和标准错误的处理方式。 make all >& compilelog.txt 这个命令会将标准输出(stdout)和标准错误&a…...
linux之less
less命令是Linux系统中一个功能强大的文件查看工具,它允许用户分页查看文件内容,并提供了多种快捷键和选项来增强用户体验。以下是less命令的一些常用操作: 基本使用 查看文件使用less命令的基本语法是less [选项] [文件名]。例如࿰…...
算法-字符串-165.比较版本号
一、题目 二、思路解析 1.思路: 比较的是两个版本号它们以“.”作为分割的部分的有效值(即数值)是否一致 2.常用方法: 1.s.split("\\规则"),将字符串按参数规则进行分割并存储在字符串数组中 String[] str …...
List与Set、数组与ArrayList、ArrayList与LinkedList的区别
List 与 Set 的区别: 项ListSet重复允许重复的对象(多个null也可以)不允许重复的对象(null也只能有一个)有序性有序的。 保持了每个元素的插入顺序。即输出顺序就是输入顺序。 有序和无序都有。 HashSet:无…...
如何在 Odoo18 视图中添加关联数据看板按钮 | 免费开源ERP实施诀窍
文 / 开源智造 Odoo亚太金牌服务 引言 关联数据看板按钮乃是 Odoo 当中的一项强效功能,它容许用户顺遂地访问相关记录,或者直接从模型的表单视图施行特定操作。它们为用户给予了对重要信息的疾速访问途径,并简化了工作流程,由此…...
Linux下mysql环境的搭建
1.mysql的下载 去MySQL官网下载mysql的linux压缩包 MySQL :: Download MySQL Community Server 如果下载慢请到网盘中自行下载 通过网盘分享的文件:mysql-8.0.40-1.el7.x86_64.rpm-bundle.tar 链接: https://pan.baidu.com/s/1vUJ-VuTwer1nLPT-haQCqw?pwd6342 提…...
视觉语言模型 Qwen2-VL
视觉语言模型 Qwen2-VL flyfish from PIL import Image import requests import torch from torchvision import io from typing import Dict from transformers import Qwen2VLForConditionalGeneration, AutoTokenizer, AutoProcessor from modelscope import snapshot_dow…...
浅谈新能源汽车感应钥匙一键启动的步骤和特点
随着汽车智能化技术的发展,无钥匙启动系统还可以与其他智能系统进行集成,如智能车载系统、远程控制系统等。这使得车主可以通过智能手机等智能设备远程控制车辆的启动、解锁、上锁等操作,进一步提升了使用的便捷性和智能化水平。新能源汽车…...
鸿蒙ArkTS语言基础语法详解
文章目录 鸿蒙ArkTS语言基础语法详解一、引言二、ArkTS语言概述1. ArkTS语言特点2. TypeScript基础语法2.1 类型注解2.2 接口2.3 泛型2.4 类的继承2.5 类的访问修饰符 三、ArkTS的基本组成3.1 装饰器3.2 UI描述3.3 自定义组件3.4 系统组件3.5 属性方法和事件方法 四、自定义组件…...
H5游戏出海如何获得更多增长机会?
海外H5小游戏的崛起给了国内众多中小厂商出海发展的机会,开发者如何在海外市场获得更多的增长机会?#APP出海# H5游戏如何在海外获得核心用户? HTML5游戏的开发与运营者们首先可以利用量多质高的HTML5游戏,维持海外用户粘性&…...
Cmake+基础命令
一、版本要求: 检查 cmake 版本号的最低要求,不满足条件时报错。 cmake_minimum_required(VERSION <version>)参数: version:最低要求的版本号 例子: # 最低要求安装3.21版本的cmake cmake_minimum_required…...
东莞便宜做网站/互联网项目推广平台有哪些
四、mysql内置函数 1.字符串函数 concat(a,b); 字符串拼接函数 insert("abcd",1,2,"我是A我是B"); 从指定位置开始替换指定长度的指定数据(起步为1) lower() 转小写 upper() 转大写 left("abcd",2) 返回ab right("abcd",2)…...
wordpress 一栏/系列推广软文范例
题 目 非线性规划的MATLAB解法及其应用(一) 问题描述非线性规划是具有非线性约束条件或目标函数的数学规划,是运筹学的一个重要分支。非线性规划是20世纪50年代才开始形成的一门新兴学科。70年代又得到进一步的发展。非线性规划在工程、管理、经济、科研、军事等方面…...
菏泽公司做网站/培训网站官网
在ps里面点击图像->画布大小。然后,高度进行相应的变化。定位一定要设置成我这样。设置好之后。选择矩形工具,把腿的地方框住。,右键,点击自由变化。然后把中心点调在最下方中心的位置 然后进行下拉。就可以调成你想要的长度了…...
领优惠券的网站怎么做/网络营销环境分析
Spark源代码阅读笔记之DiskStore BlockManager底层通过BlockStore来对数据进行实际的存储。BlockStore是一个抽象类,有三种实现:DiskStore(磁盘级别的持久化)、MemoryStore(内存级别的持久化)和TachyonStor…...
广东恒力建设工程有限公司网站/西安网站设计公司
防止人为误操作MySQL数据库技巧一例(本题来自老男孩培训内部学生问题,属于数据库安全技巧)在若干年前,老男孩亲自遇到一个“命案”,老大登录数据库update一个记录,结果忘了加where,于是悲剧发生…...
做b612表情的素材网站/东莞网络推广策略
CentOS7 kernel-3.10.0-693.el7.centos.toa.x86_64.rpm 网盘链接:https://pan.baidu.com/s/1cXB_3qPOnTiIGijFlQ_uzw将文件上传到服务器。 直接rpm安装会报错,如下: [rootlocalhost CentOS 7.2 64]# rpm -ivh kernel-3.10.0-693.el7.centos.t…...