windows系统版本号
操作系统
版本号
Windows 11
10.0*
Windows 10
10.0*
Windows Server 2022
10.0*
Windows Server 2019
10.0*
Windows Server 2016
10.0*
Windows 8.1
6.3*
Windows Server 2012 R2
6.3*
Windows 8
6.2
Windows Server 2012
6.2
Windows 7
6.1
Windows Server 2008 R2
6.1
Windows Server 2008
6.0
Windows Vista
6.0
Windows Server 2003 R2
5.2
Windows Server 2003
5.2
Windows XP 64 位版本
5.2
Windows XP
5.1
Windows 2000
5.0
对于已为Windows 8.1或Windows 10清单的应用程序。 未为Windows 8.1或W ...
引言
在做项目过程中库函数是一个很重要的模块,而我们往往将每个功能独立成一个函数,这样能够提高函数的复用性。
根据使用过的场景,项目过程中对库函数的引用总共3种方式:
方式
链接时刻
库指定时刻
特点
静态链接
编译时
编译时
编译时检查链接错误,编入运行程序(运行程序独立)
动态链接
运行时
编译时
编译时检查链接错误,运行时调入依赖库
动态链接
运行时
运行时
编译时不做任何检查,运行时调入依赖库
其中前两种是我们熟悉的,最后一种是“完全”动态方式,包括库文件的指定都是由代码完成的。
这里先重点讲解最后一种,后续会在补充,如果忘记了,可以留言催一下。
链接静态库
静态链接动态库
动态链接动态库
定义了一组接口函数,但无法得知具体的实现细节,可能是由别人实现,程序在运行时根据某个传入的参考,动态调用这一组接口,并按照特定的方式运行,在C++中多少像虚函数的特点-提供接口而不在乎具体的实现。
这种场景比较适合于一个框架(开发者A),多个不同的细节实现(开发者B,C…)的一种应用。
从上面的描述,要完成本项功能,包括调用框架的编写(相当于服务器端)和被 ...
video: https://www.bilibili.com/video/BV1Lf4y1o7xM
notes_zh: https://mlc.ai/zh/chapter_end_to_end/index.html
notes_en: https://mlc.ai/chapter_end_to_end/index.html
ipynb: https://github.com/mlc-ai/notebooks/blob/main/4_Build_End_to_End_Model.ipynb
端到端模型执行
前言
大多数 MLC 过程可以看作是张量函数之间的转换。我们打算在上一节课中回答的主要问题是:
什么是可能的张量函数抽象表达形式?
什么是可能的张量函数变换?
在上一课中,我们主要关注点是元张量函数。在本次讲座中,我们将讨论如何构建端到端模型。
准备工作
首先,我们将导入必要的依赖项。
12345678import tvmfrom tvm.ir.module import IRModulefrom tvm.script import tir as T, relax as R ...
slides: https://mlc.ai/summer22-zh/slides/2-TensorProgram.pdf
video: https://www.bilibili.com/video/BV1kY411N7JA
note_zh: https://mlc.ai/zh/chapter_tensor_program/
note_en: https://mlc.ai/chapter_tensor_program/
元张量函数
在上一章的概述中,我们介绍到机器学习编译的过程可以被看作张量函数之间的变换。一个典型的机器学习模型的执行包含许多步将输入张量之间转化为最终预测的计算步骤,其中的每一步都被称为元张量函数 (primitive tensor function)。
在上面这张图中,张量算子 linear, add, relu 和 softmax 均为元张量函数。特别的是,许多不同的抽象能够表示(和实现)同样的元张量函数(正如下图所示)。我们可以选择调用已经预先编译的框架库(如 torch.add 和 numpy.add)并利用在 Python 中的实现。在实践中,元张量函数 ...
slides: https://mlc.ai/summer22-zh/slides/2-TensorProgram.pdf
video: https://www.bilibili.com/video/BV1c94y1d7rW
note_zh: https://mlc.ai/zh/chapter_tensor_program/case_study.html
note_en: https://mlc.ai/chapter_tensor_program/case_study.html
exercise: https://mlc.ai/zh/chapter_tensor_program/tensorir_exercises.html
ipynb: https://github.com/mlc-ai/notebooks/blob/main/3_TensorIR_Tensor_Program_Abstraction_Case_Study_Action.ipynb
TensorIR: 张量程序抽象案例研究
安装相关的包
为了本课程的目标,我们会使用 TVM (一个开源的机器学习编译框架)中一些 ...
video: https://www.bilibili.com/video/BV1YT411j7c2
notes_zh: https://mlc.ai/zh/chapter_auto_program_optimization/index.html
notes_en: https://mlc.ai/chapter_auto_program_optimization/index.html
ipynb: https://github.com/mlc-ai/notebooks/blob/main/6_Integration_with_Machine_Learning_Frameworks.ipynb
与机器学习框架的整合
前言
在过去的章节中,我们学习了机器学习编译的抽象和张量函数之间的变换。
本章将讨论如何将机器学习模型从现有的机器学习框架引入 MLC 流程。
准备工作
首先,我们导入必要的依赖项。
12345678import tvmfrom tvm.ir.module import IRModulefrom tvm.script import tir as T, relax as R ...
video:
notes_zh:
notes_en:
ipynb:
video: https://www.bilibili.com/video/BV1ST411J7mR
notes_zh: https://mlc.ai/zh/chapter_auto_program_optimization/index.html
notes_en: https://mlc.ai/chapter_auto_program_optimization/index.html
ipynb: https://github.com/mlc-ai/notebooks/blob/main/5_Automatic_Program_Optimization.ipynb
自动程序优化
前言
在过去的章节中,我们学习了如何构建元张量函数并将它们连接起来以进行端到端的模型执行。到目前为止,我们使用了三种主要的抽象类型。
驱动高层执行的计算图抽象,
元张量函数的抽象,
通过注册环境函数从而能被调用的库函数。
所有这些元素都封装在一个 IRModule 中。大多数 MLC 过程可以看作是张量函数之间的变换。
有许多不同的方法可以变换同一个程序。本章将讨论自动化一些流程的方法。
准备工作
首先 ...
工具查编码
通过在线网站查询字符编码,汉字字符集编码查询
程序判断编码
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667//Encode.h#include <iostream>#include <string>#include <Windows.h>using namespace std; //将wstring转换成string string wstring2string(wstring wstr,UINT nCode){ string result; //获取缓冲区大小,并申请空间,缓冲区大小事按字节计算的 int len = WideCharToMultiByte(nCode, 0, wstr.c_str(), wstr.size(), NULL, 0, NULL, NULL); char* buffer ...
引言
C++的项目,字符编码是一个大坑,不同平台之间的编码往往不一样,如果不同编码格式用一套字符读取格式读取就会出现乱码。因此,一般都是转化成UTF-8这种平台通用,且支持性很好的编码格式。
字符编码知识
先简单介绍一下Unicode、UTF-8、ANSI之间的概念。
Unicode:国际通用编码,使用两个字节表示一个字符,可以表示世界上任何文字和符号。
Unicode只是一个符号集, 它只规定了符号的二进制代码, 却没有规定这个二进制代码应该如何存储。
UTF-8:UTF-8是Unicode实现方式之一。
可变长度编码,可以表示Unicode标准中的任何一个字符,且编码中第一个字节与ASCII兼容,UTF-8中英文占一个字符,即英文字符编码结果相同
中文因为需要三个字节,与ASCII码不同,故有乱码
ANSI:本地码,与系统的默认编码相关
中文windows: GBK
英文windows: ASICII
繁体windows: BIG5
GB2312/BIG5:中国制定的编码规范
GB2312: 简体中文
BIG5: 繁体中文
GBK: 亚洲双字节字符 ...
编码篇
ifstream 无法打开包含中文路径的文件,且打开的文件内容是utf-8格式,若文件出现无法打开/文件内容出现乱码,需要将字符串转为gbk格式123456789101112131415161718192021222324252627282930#include <iostream>#include <fstream>#include <string>#include <vector>#include <windows.h>using namespace std;string UTF8ToGB(const char* str) { string result; WCHAR *strSrc; LPSTR szRes; //获得临时变量的大小 int i = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); strSrc = new WCHAR[i + 1]; MultiByteToWideChar(CP_UTF8, ...
引言
在深度学习模型部署阶段,常常需要考虑硬件资源问题,如显存大小,IO读写速度CPU使用率,内存占用等问题,对于使用CPU环境的模型,这些问题显得更加重要。
这篇主要是针对 ONNXRUNTIME模型在 CPU环境下 C++部署时出现的CPU占用过高以及内存问题进行说明,并尝试解决。主要包含三个部分:
编写占用CPU高的小程序,便于测试
编写获取系统CPU使用率
编写限制CPU使用率
一些项目过程中的经验
Demo
主要通过循环的方式,占用CPU,另外由于处理器多核的缘故,需要创建线程来实现所有核心CPU的使用率跑满。
12345678910111213141516171819202122232425262728293031323334353637383940// windows#ifdef _WIN32#define(_WIN32)#include <windows.h>#include <iostream>#include <cstdlib>using namespace std;DWORD WINAPI FunProc(LPVOID lp ...
在Post not found: 机器学习编译器代码生成相关-MLIR-Dialect 机器学习编译器代码生成相关-MLIR-Dialect中我分享了对编译器和中间表示 (IR) 演进趋势的整体理解, 也讨论了 LLVM IR, SPIR-V, 和 MLIR 所要解决的问题以及相应的设计着眼点。 今天对 MLIR 做进一步展开,分析一下机器学习相关的 dialect 体系。
值得注意的是,MLIR 是一个编译器基础设施,它可以用来编写各种领域专用编译器,并不限于机器学习。 不过机器学习确实是 MLIR 得到最活跃开发和应用的领域,尤其是用来转换各种 ML 模型,以及支持各种异构硬件。
基础组件
编译器的一大优势是 可组合性 (composability) 。 如果功能甲、乙、丙分别得到了实现,那么它们的各种组合也自然而然会得到支持。 这种特性是编译器与算子库 (library) 的核心区别之一;在算子库中,不同的组合可能需要经由完全不同的手写代码来实现。 通过把指数级问题变成线性问题,编译器长期而言可以缩减大量的工程投入。
为实现这种可组合性,我们需要 分解问题而后开发适宜的基础组件 ...
编译器 (compiler) 通常是各种提高开发效率的工具链中不可或缺的部分。 编译器一般被为黑箱,吃进高层次的源程序,产生语义不变的低层次机器码。 当然,编译器也是有其内部结构的,中间表示 (intermediate representation) 串联起编译器内各层级和模块。
中间表示对编译器至关重要,也如编译器一样百花齐放。 我在日常工作中有幸能够涉及三种主流编译器中间表示或者基础设施——LLVM IR, SPIR-V, 以及 MLIR, 尤其对于后两种,我都参与了早期的开发。 我打算用一系列文章记录自己对于编译器以及中间表示的理解,希望对感兴趣的人有所帮助。
这是开坑第一篇,主要讨论我个人对于编译器以及中间表示的演进历史以及发展趋势的理解。 着眼点在于为什么现有中间表示会设计成它们当前的形态,而非具体的机制以及如何使用。 后者已经有详尽的规范和教程可以参考。 话题所致,此篇会比较抽象,或者用最近比较拉风的词,形而上 (meta) 😉 ,在后续的文章中我会更加具体。 另外,此篇也会尽量使用比较和类比,因为一般而言,借助于已熟悉概念来理解新概念会比较高效。 讨论偶尔也会涉及非编译 ...
今天来说说,CMake 中稍许有些难度的部分:交叉编译。
虽说交叉编译有些难度,但是相对于其它的工具,CMake 的交叉编译支持还是很强大的,用一个 CMAKE_TOOLCHAIN_FILE 文件参数来制定交叉编译工具链就能解决大部分问题了。
例子
下面来说说一个例子,比如我们现在需要编译 aarch64(即 ARM architecture 64 位)上的可执行程序,或者库,我们就需要类似以下的工具链配置:
123456789101112131415161718192021222324252627282930313233343536373839set(CMAKE_SYSTEM_NAME Linux)set(CMAKE_SYSTEM_PROCESSOR aarch64)# 交叉编译器set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)# 设置搜索规则,这里需要重点注意,因为交叉编译所需要的依赖# 一般不会放在系统目录下,而是会有专门的路径set(CMAKE_FIN ...
引言
久等啦!模型部署入门教程更新啦!前几期教程中,我们系统学习了 PyTorch & ONNX 相关知识。大家或许学会了许多 API 用法,却不清楚怎么用到自己的项目中。今天,我们来综合之前学到的,实现一个 PyTorch-ONNX 精度对齐工具。
精度对齐,是模型部署中重要的一个环节。在把深度学习框架模型转换成中间表示模型后,部署工程师们要做的第一件事就是精度对齐,确保模型的计算结果与之前相当。精度对齐时最常用的方法,就是使用测试集评估一遍中间表示模型,看看模型的评估指标(如准确度、相似度)是否下降。
而在 PyTorch 到 ONNX 这条部署路线上,这种精度对齐方式有一些不便:一旦我们发现 PyTorch 模型和 ONNX 模型的评估指标有了出入,我们很难去追踪精度是在哪一个模块出了问题。这是因为 PyTorch 和 ONNX 模块总是难以对应。如下面的例子所示:
假设我们现在有一个由很多卷积块 convs1, convs2... 组成的网络,我们想对齐 PyTorch 模型和 ONNX 模型的精度。第一步,我们想比较第一个卷积块的输出 x = self.convs1 ...
slides: https://mlc.ai/summer22-zh/slides/1-Introduction.pdf
video: https://www.bilibili.com/video/bv15v4y1g7EU
note_zh: https://mlc.ai/zh/chapter_introduction/
note_en: https://mlc.ai/chapter_introduction/
概述
机器学习应用程序已经无处不在。我们的智能家居设备由自然语言处理(NLP)和语音识别模型驱动,自动驾驶技术依赖于计算机视觉模型作为支柱,还有推荐系统帮助我们在探索时发现新内容。
同样有趣的是AI应用的部署环境是非常丰富的。推荐系统算法通常由大型公司部署在云平台上;当我们谈论自动驾驶时,我们首先想到的是强大的 GPU 或车辆上的专用计算设备;我们使用手机上的智能应用程序来识别花园中的花朵以及如何照料它们;以及越来越多的物联网传感器也在内置微型芯片中运行着简单的AI算法。
如果我们深入研究这些环境,就会涉及到更多环境多样性。即使对于属于同一类别的环境(例如云),也存在关于硬件 ...
video:
notes_zh:
notes_en:
ipynb:
video:
notes_zh:
notes_en:
ipynb:
video:
notes_zh:
notes_en:
ipynb:
video:
notes_zh:
notes_en:
ipynb:
当字符串中包含中文,字符数的统计会有问题,体现在调试时,提示字符串中的字符无效,原因是字符编码为utf-8而IDE显示了ansi编码,导致如此,将多字符转为宽字符,即ANSI转GBK
源码
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384// CharNums.h#include <Windows.h>#include <tchar.h>#include <vector>#include <string>#pragma warning(disable:4996)using namespace std;// 宽字符 -> 多字符std::string WStringToString(const std::wstring& ws){ std:: ...
计算给定的字符的字符长度,中文,英文,数字,符号均为一个字符
在线编译测试:https://onlinegdb.com/zih0Wi3AZ
1234567891011121314151617181920212223242526272829303132333435#include <iostream>#include <vector>int splitWord(const std::string & word ){ std::vector<std::string> characters; int num = word.size(); int i = 0; while(i < num) { int size = 1; if(word[i] & 0x80) { char temp = word[i]; temp <<= 1; do{ ...
CMake系列
【CMake系列】(一)入门
【CMake系列】(二)第三方依赖管理
【CMake系列】(三)ExternalProject-实践
【CMake系列】(四)用GoogleTest测试
【CMake系列】(五)安装、打包与导出
【CMake系列】(六)用Doxygen、Sphinx与Breathe创建文档
【CMake系列】(七)常用变量、函数以及模块
【CMake系列】(八)交叉编译
【CMake系列】(九)实战之如何下载依赖
【CMake系列】(十)编译速度以及程序性能优化相关
CMAKE官方教程
Post not found: Development_tools/CMAKE/CMAKE官方教程(中文版) CMAKE官方教程(中文版)
CMAKE实战篇
Post not found: Development_tools/CMAKE/CMAKE实战篇之文件下载解压 CMAKE实战篇之文件下载解压
今天我们来说说,CMake 这个现代 C++ 项目的利器。
前言
为什么我们需要 CMake ? 对于 C++ 开发者来说,他们会习惯于使用 GNU Make 来编译 C++ 项目,对于简单项目来说,这无可厚非,再加上有那么多的开源工具可用,尤其是 autotools 系列,用起来还是挺方便的。目前仍有非常多的 C++ 项目,需要你先使用 ./configure 来预处理,然后再进行编译,这比只用 Make 来说,方便很多倍,也就是对初学者非常友好 (高阶用户在此就不说了,毕竟如能把 Vim 用到飞起的高手并不多)。
在我个人看来,autotools 系列不那么简洁(当我看见当前目录生成一堆临时文件的时候,会非常讨厌,相对的,CMake 可以有专门的编译目录真是拯救了我的强迫症),由于没有怎么使用过,不便于说出更多其它意见,也无法细致对比。有兴趣的也可以看看 What are the differences between Autotools, Cmake and Scons? 上的讨论。
从入手难度来说,CMake 是初学者的福音,不过有点麻烦的是,你需要学习一门新的语言,只是相对于 ...
用了 CMake 较长一段时间后,在笔记本里面记录了不少知识,这些知识其实应该放在这个系列文章的开始来讲,因为算是很入门的部分,这里就简单总结下。
配置期间
生成配置文件
12345configure_file("${PROJECT_SOURCE_DIR}/include/config.h.in" "${PROJECT_BINARY_DIR}/include/config.h")
比如,你可以将 cmake 中,project 命令中设置的版本,通过这个方式传递给程序:
12345678910111213141516// config.h.in#pragmaonce#defineMY_VERSION_MAJOR @PROJECT_VERSION_MAJOR@#defineMY_VERSION_MINOR @PROJECT_VERSION_MINOR@#defineMY_VERSION_PATCH @PROJECT_VERSION_PATCH@#defineMY_VERSION_T ...
Post not found: 【CMake系列】(二)第三方依赖管理 【CMake系列】(二)第三方依赖管理 说了第三方依赖管理,提到了我们团队在使用 `ExternalProject` 来管理依赖,这次来说说具体实践,以及一个基于 CMake 的开源依赖管理工具 [vcpkg](https://github.com/microsoft/vcpkg)。
ExternalProject 实践
来看看它长什么样:
1234ExternalProject_Add(<name> [<option>...])ExternalProject_Add_Step(<name> <step> [<option>...])ExternalProject_Get_PropertyExternalProject_Add_StepTargets(<name> [NO_DEPENDS] <step1> [<step2>...])
是不是很简单,显然不是,文档里写成这样是因为参数太多了,惊不惊喜?
其实大部分参数用不到 ...