点击上方“视学算法”,选择加"星标"或“置顶

重磅干货,第一时间送达

作者:Tirthajyoti Sarkar

本文转载自:机器之心  |  编辑:蛋酱

算法完美是重要的,但更重要的是成功部署,这篇文章能够帮助你了解有关代码内存占用的一切。

在进行机器学习任务时,你需要学会使用代码快速检查模型的内存占用量。原因很简单,硬件资源是有限的,单个机器学习模块不应该占用系统的所有内存,这一点在边缘计算场景中尤其重要。

比如,你写了一个很棒的机器学习程序,或者搭建了一个不错的神经网络模型,然后想在某些 Web 服务或 REST API 上部署模型。或者你是基于工厂传感器的数据流开发了模型,计划将其部署在其中一台工业计算机上。

这时,你的模型可能是硬件上运行的几百个模型之一,所以你必须对内存占用峰值有所了解。否则多个模型同时达到了内存占用峰值,系统可能会崩溃。

因此,搞清楚代码运行时的内存配置文件(动态数量)非常重要。这与模型的大小和压缩均无关,可能是你事先已经将其保存在磁盘上的特殊对象,例如 Scikit-learn Joblib dump、Python Pickle dump,TensorFlow HFD5 等。

Scalene:简洁的内存 / CPU/GPU 分析器

首先要讨论的是 Scalene,它是一个 Python 的高性能 CPU 和内存分析器,由马萨诸塞大学研发。其 GitHub 页面是这样介绍的:「 Scalene 是适用于 Python 的高性能 CPU、GPU 和内存分析器,它可以执行许多其他 Python 分析器无法做到的事情,提供详细信息比其他分析器快几个数量级。」

安装

它是一个 Python 包,所以按照通常方法安装:

pip install scalene

这样适用于 Linux OS,作者没有在 Windows 10 上进行测试。

在 CLI 或 Jupyter Notebook 内部使用 

Scalene 的使用非常简单:

scalene <yourapp.py>

也可以使用魔术命令在 Jupyter notebook 中使用它:

%load_ext scalene

输出示例

下面是一个输出示例。稍后将对此进行更深入的研究。

这些是 Scalene 一些很酷的功能:

  • 行和函数:报告有关整个函数和每个独立代码行的信息;

  • 线程:支持 Python 线程;

  • 多进程处理:支持使用 multiprocessing 库;

  • Python 与 C 的时间:Scalene 用在 Python 与本机代码(例如库)上的时间;

  • 系统时间:区分系统时间(例如,休眠或执行 I / O 操作);

  • GPU:报告在英伟达 GPU 上使用的时间(如果有);

  • 复制量:报告每秒要复制的数据量;

  • 泄漏检测:自动查明可能造成内存泄漏的线路。

ML 代码具体示例

接下来看一下 Scalene 用于内存配置标准机器学习代码的工作。对三个模型使用 Scikit-learn 库,并利用其综合数据生成功能来创建数据集。

对比的是两种不同类型的 ML 模型:

  • 多元线性回归模型;

  • 具有相同数据集的深度神经网络模型。

线性回归模型

使用标准导入和 NUM_FEATURES 、 NUM_SMPLES 两个变量进行一些实验。

这里没有展示数据生成和模型拟合代码,它们是非常标准的。作者将拟合的模型另存为 pickled dump,并将其与测试 CSV 文件一起加载以进行推断。

为了清晰起见,将所有内容置于 Scalene 执行和报告环境下循环运行。

当运行命令时:

$ scalene linearmodel.py --html >> linearmodel-scalene.html

将这些结果作为输出。注意,此处使用了 --html 标志并将输出通过管道传输到 HTML 文件,以便于报告。

令人惊讶的是,内存占用几乎完全由外部 I / O(例如 Pandas 和 Scikit-learn estimator 加载)控制,少量会将测试数据写到磁盘上的 CSV 文件中。实际的 ML 建模、Numpy、Pandas 操作和推理,根本不会影响内存。

我们可以缩放数据集大小(行数)和模型复杂度(特征数),并运行相同的内存配置文件以记录各种操作在内存消耗方面的表现。结果显示在这里。

此处,X 轴代表特征 / 数据点集。注意该图描绘的是百分比,而不是绝对值,展示了各种类型操作的相对重要性。

从这些实验中得出的结论是,Scikit-learn 线性回归估计非常高效,并且不会为实际模型拟合或推理消耗大量内存。

但就代码而言,它确实有固定的内存占用,并在加载时会消耗大量内存。不过随着数据大小和模型复杂性的增加,整个代码占用百分比会下降。如果使用这样的模型,则可能需要关注数据文件 I / O,优化代码以获得更好的内存性能。

深度神经网络如何?

如果我们使用 2 个隐藏层的神经网络(每个隐藏层有 50 个神经元)运行类似的实验,那么结果如下所示。

代码地址:https://github.com/tirthajyoti/Machine-Learning-with-Python/blob/master/Memory-profiling/Scalene/mlp.py

与线性回归模型不同,神经网络模型在训练 / 拟合步骤中消耗大量内存。但是,由于特征少且数据量大,拟合占用的内存较少。此外,还可以尝试各种体系结构和超参数,并记录内存使用情况,达到合适的设置。

复现说明

如果你使用相同的代码复现实验,结果可能会因硬件、磁盘 / CPU / GPU / 内存类型的不同而大相径庭。

一些关键建议 

  • 最好在代码中编写专注于单个任务的小型函数;

  • 保留一些自由变量,例如特征数和数据点,借助最少的更改来运行相同的代码,在数据 / 模型缩放时检查内存配置文件;

  • 如果要将一种 ML 算法与另一种 ML 算法进行比较,请让整体代码的结构和流程尽可能相同以减少混乱。最好只更改 estimator 类并对比内存配置文件;

  • 数据和模型 I / O(导入语句,磁盘上的模型持久性)在内存占用方面可能会出乎意料地占主导地位,具体取决于建模方案,优化时切勿忽略这些;

  • 出于相同原因,请考虑比较来自多个实现 / 程序包的同一算法的内存配置文件(例如 Keras、PyTorch、Scikitlearn)。如果内存优化是主要目标,那么即使在功能或性能上不是最佳,也必须寻找一种占用最小内存且可以满意完成工作的实现方式;

  • 如果数据 I / O 成为瓶颈,请探索更快的选项或其他存储类型,例如,用 parquet 文件和 Apache Arrow 存储替换 Pandas CSV。可以看看这篇文章:

《How fast is reading Parquet file (with Arrow) vs. CSV with Pandas?》

https://towardsdatascience.com/how-fast-is-reading-parquet-file-with-arrow-vs-csv-with-pandas-2f8095722e94

Scalene 能做的其他事

在本文中,仅讨论了内存分析的一小部分,目光放在了规范机器学习建模代码上。事实上 Scalene CLI 也有其他可以利用的选项:

  • 仅分析 CPU 时间,不分析内存;

  • 仅使用非零内存减少资源占用;

  • 指定 CPU 和内存分配的最小阈值;

  • 设置 CPU 采样率;

  • 多线程并行,随后检查差异。

最终验证(可选)

在资源较少的情况下,你最好托管一个验证环境 / 服务器,该服务器将接受给定的建模代码(如已开发),并通过这样的内存分析器运行它以创建运行时统计信息。如果它通过内存占用空间的预定标准,则只有建模代码会被接受用于进一步部署。

总结

在本文中,我们讨论了对机器学习代码进行内存配置的重要性。我们需要使其更好地部署在服务和机器中,让平台或工程团队能够方便运用。分析内存也可以让我们找到更高效的、面向特定数据或算法的优化方式。

希望你能在使用这些工具和技术进行机器学习部署时能够获得成功。

原文链接:https://towardsdatascience.com/how-much-memory-is-your-ml-code-consuming-98df64074c8f

点个在看 paper不断!

你写的ML代码占多少内存?这件事很重要,但很多人还不懂相关推荐

  1. 你写的机器学习代码占多少内存?这件事很重要,但很多人还不懂

    作者 | Tirthajyoti Sarkar 编译 | 蛋酱 来源 | 机器之心 算法完美是重要的,但更重要的是成功部署,这篇文章能够帮助你了解有关代码内存占用的一切. 在进行机器学习任务时,你需要 ...

  2. sas 检测到开型代码语句的递归_对于标准答案的递归很多人都看不懂,其实就是一个深度优先的遍历。我写了段伪代码,将递归步骤还原并注释了一下,供大家参考,希望大家有所收获。...

    源自:7-5 Python之递归函数 对于标准答案的递归很多人都看不懂,其实就是一个深度优先的遍历.我写了段伪代码,将递归步骤还原并注释了一下,供大家参考,希望大家有所收获. #if条件不成立的省略 ...

  3. 用C++写一个简单小病毒(零基础奶妈级教学,不可能学完还不懂)

    相信大家都玩过这样的一个批处理代码吧 :1 start cmd goto 1 把这些代码复制去一个txt文件,然后更改后缀为.bat 或.cmd,就可以实现弹窗炸弹 但是,作为一个病毒,这个简单恶搞代 ...

  4. java中什么方法用来清空流_这个真的写的很细,JavaIO中的常用处理流,看完只有10%的人还不懂了...

    JavaIO中的常用处理流 在前面,我们了解了有关JavaIO流基础的使用,其中对于IO流来说最基础的四大基类就是InputStream.OutputStream.Reader.Writer.而我们对 ...

  5. 写代码犹如写文章: “大师级程序员把系统当故事来讲,而不是当做程序来写” | 如何架构设计复杂业务系统? 如何写复杂业务代码?

    写代码犹如写文章: "大师级程序员把系统当故事来讲,而不是当做程序来写" | 如何架构设计复杂业务系统? 如何写复杂业务代码? Kotlin 开发者社区 "大师级程序员把 ...

  6. 代码的印象派:写点好代码吧

    最近有一位猎头顾问打电话询问是否有换工作的意向,对推荐的公司和职位的描述为:"我们这里有一家非常关注软件质量的公司,在寻找一位不仅能完成有挑战的软件开发任务,并且还对代码质量有非常高追求的软 ...

  7. python函数的组成要素_python函数要素有哪些?这7点是你写好python代码的关键

    [摘要]对于python小白来说,写好一个python代码并不容易,不过你知道python函数要素有哪些?这7点是你写好python代码的关键,如果你想学好python,那么本文内容一定要自己试试,毕 ...

  8. 阿里高级技术专家方法论:如何写复杂业务代码?

    阿里妹导读:张建飞是阿里巴巴高级技术专家,一直在致力于应用架构和代码复杂度的治理.最近,他在看零售通商品域的代码.面对零售通如此复杂的业务场景,如何在架构和代码层面进行应对,是一个新课题.结合实际的业 ...

  9. 资深技术专家推荐:如何写复杂业务代码-阿里实践

    一个复杂业务的处理过程 业务背景 简单的介绍下业务背景,零售通是给线下小店供货的B2B模式,我们希望通过数字化重构传统供应链渠道,提升供应链效率,为新零售助力.阿里在中间是一个平台角色,提供的是Bsb ...

最新文章

  1. boost::function_types::parameter_types用法的测试程序
  2. Vue2 封装的 Quill 富文本编辑器组件 Vue-Quill-Editor
  3. 第一届大数据科学与工程国际会议(2016)精彩荟萃
  4. 轴承配合公差表查询_如何选择轴承公差和配合,才能更好保证电机轴承系统的运行?...
  5. Jenkins 官网文档翻译汇总
  6. Hadoop1重新格式化HDFS
  7. (已更新)【全开源商城小程序源码】ThinkPHP 5.1+带后台商城源码程序+带详细安装使用文档
  8. mysql 2000安装教程_Win10 64位安装个人版SQL2000图文教程
  9. (IoT物联网)天线的设计步骤 - 完整收藏版
  10. 广西大学计算机科学与技术调剂,广西大学计算机与电子信息学院2021年硕士研究生招生考试复试成绩公示(调剂)...
  11. Deilphi IDE 扩展工具:cnPack DelForEx
  12. gsp计算机管理权限,新gsp计算机权限设置
  13. 营业收费系统 建立报表库服务器,浅谈计算机在自来水收费系统的重要应用
  14. python单例模式selenium driver实现单例
  15. 热敏打印机的工作原理
  16. java的listroots_Java File listRoots()用法及代码示例
  17. 福布斯中国奢侈品市场调查
  18. 【斯坦福21秋(李沐)】实用机器学习(学习笔记)——1.1课程介绍
  19. LEFT JOIN左连接示例
  20. 美摄SDK 局部特效接入文档

热门文章

  1. 设计模式解析(五)——几种设计模式之Facade和Adapter
  2. C++_volatile限定修饰符 Pair类型
  3. LeetCode实战:两数相加
  4. iOS15.4 来袭:新增“男妈妈”表情及口罩面容解锁、AirTags 反跟踪等新功能
  5. 新年新气象,100 行 Python 代码制作动态鞭炮
  6. 想提高代码水平,做到这点就够了
  7. 2020年中国AI算力报告发布:超大算法模型挑战之下,公共AI算力基建是关键
  8. 英特尔第11代酷睿处理器TigerLake发布,集成Xe GPU,采用10nm制程技术
  9. 中文repo“霸榜”GitHub Trending,国外开发者不开心了
  10. 吴恩达团队:神经网络如何正确初始化?