Transformer 估算 101

本文主要介绍用于估算 transformer 类模型计算量需求和内存需求的相关数学方法。

引言

其实,很多有关 transformer 语言模型的一些基本且重要的信息都可以用很简单的方法估算出来。不幸的是,这些公式在 NLP 社区中鲜为人知。本文的目的是总结这些公式,阐明它们是如何推导出来的及其作用。

注意: 本文主要关注训练成本,该成本主要由 GPU 的 VRAM 主导。如果你想知道有关推理成本 (通常由推理延迟主导) 的信息,可以读读 Kipply 写的 这篇精彩博文。

算力要求

下式可用于估算训练一个 transformer 模型所需的算力成本:

\[C \approx \tau T = 6PD \]

这里:

  • \(C\) 是训练 transformer 模型所需的计算量,单位为总浮点运算数 (FLOP)
  • \(C=C_{\text {前向}}+C_{\text {后向}}\)
  • \(C_{\text {前向}} \approx 2PD\)
  • \(C_{\text {后向}} \approx 4PD\)
  • \(\tau\) 是训练集群的实际总吞吐量: \(\tau=\text {GPU 数} \times \text {每 GPU 的实际每秒浮点运算数 (实际 FLOPs) }\),单位为 FLOPs
  • \(T\) 是训练模型所花费的时间,以秒为单位
  • \(P\) 是 transformer 模型的参数量
  • \(D\) 是数据集大小,表示为数据集的总词元数

该式由 OpenAI 的缩放定律论文 和 DeepMind 的缩放定律论文 提出并经其实验验证。想要获取更多信息,可参阅这两篇论文。

下面,我们讨论一下 \(C\) 的单位。 \(C\) 是总计算量的度量,我们可以用许多单位来度量它,例如:

  • FLOP - 秒,单位为 \({\text {每秒浮点运算数}} \times \text {秒}\)
  • GPU - 时,单位为 \(\text {GPU 数}\times\text {小时}\)
  • 缩放定律论文倾向于以 PetaFLOP - 天 为单位,即单位为 \(10^{15} \times 24 \times 3600\)

这里需要注意 \(\text {实际 FLOPs}\) 的概念。虽然 GPU 的规格书上通常只宣传其理论 FLOPs,但在实践中我们从未达到过这些理论值 (尤其在分布式训练时!)。我们将在计算成本这一小节列出分布式训练中常见的 \(\text {实际 FLOPs}\) 值。

请注意,上面的算力成本公式来自于 这篇关于 LLM 训练成本的精彩博文。

参数量与数据集的权衡

严格来讲,你可以随心所欲地使用任意数量的词元来训练 transformer 模型,但由于参与训练的词元数会极大地影响计算成本和最终模型的性能,因此需要小心权衡。

我们从最关键的部分开始谈起: “计算最优” 语言模型。“Chinchilla 缩放定律”,得名于提出 “计算最优” 语言模型论文中所训练的模型名,指出计算最优语言模型的 参数量数据集大小 的近似关系满足: \(D=20P\)。该关系成立基于一个前提条件: 使用 1,000 个 GPU 1 小时和使用 1 个 GPU 1,000 小时成本相同。如果你的情况满足该条件,你应该使用上述公式去训练一个性能最优且 GPU - 时 成本最小的模型。

我们不建议在少于 200B 词元的数据集上训练 LLM。 虽然对于许多模型尺寸来说这是 “Chinchilla 最优” 的,但生成的模型通常比较差。对于几乎所有应用而言,我们建议确定你可接受的推理成本,并训练一个满足该推理成本要求的最大模型。

计算成本的经验值

Transformer 模型的计算成本通常以 GPU - 时FLOP - 秒 为单位。

  • GPT-NeoX 的 实际 TFLOP/s 在正常注意力机制下达到 150 TFLOP/s/A100,在 Flash 注意力机制下达到 180 FLOP/s/A100。这与其他高度优化的大规模计算库一致,例如 Megatron-DS 的值是在 137 和 163 TFLOP/s/A100 之间。
  • 一个通用的经验法则是 实际 TFLOP/s 可至 120 TFLOP/s/A100 左右。如果你得到低于 115 TFLOP/s/A100 的值,可能是你的模型或硬件配置有问题。
  • 借助 InfiniBand 等高速互连设备,你可以在数据并行维度上实现线性或亚线性扩展 (即增加数据并行度应该以近乎线性的方式增加整体吞吐量)。下图显示了在橡树岭国家实验室 (Oak Ridge National Lab) 的 Summit 超级计算机上测试出的 GPT-NeoX 库的扩展性。请注意,这张图用的是 V100,而本文中的其他大多数例子都是基于 A100 的。

GPT-NeoX 扩展性

内存需求


Transformer 模型通常由其 参数尺寸 来描述。但是,根据给定一组计算资源确定要训练哪些模型时,你需要知道 该模型将占用多少空间 (以字节为单位)。这不仅需要考虑你的本地 GPU 可以推理多大的模型,还需要考虑给定训练集群中的总可用 GPU 内存可供训练多大的模型。

推理

模型权重

模型权重

大多数 transformer 模型都使用 混合精度进行训练,可以是 fp16 + fp32 或是 bf16 + fp32。混合精度降低了模型训练和推理所需的内存量。推理时,我们还可以将语言模型从 fp32 转换为 fp16 甚至 int8,而没有实质性的精度损失。下面我们看看在不同的数据类型下,模型所需内存有什么不同 (以字节为单位):

  • 对 int8 而言,\(\text {模型内存}=1 \text { 字节} /\text {参数}\cdot \text {参数量}\)
  • 对 fp16 和 bf16 而言,\(\text {模型内存}=2 \text { 字节} /\text {参数} \cdot \text {参数量}\)
  • 对 fp32 而言,\(\text {模型内存}=4 \text { 字节} /\text {参数}\cdot \text {参数量}\)

推理总内存

除了存储模型权重所需的内存外,实际中前向传播过程中还会有少量额外开销。根据我们的经验,此开销在 20% 以内,该比例通常与模型无关。

总的来说,回答 “这个模型是否适合推理” 这一问题,可以用下述公式来获得不错的估计:

\(\text {推理总内存} \approx 1.2 \times \text {模型内存}\)

本文不会深究该开销的来源,留待后面的文章来阐述。在本文的后续部分,我们将主要关注模型训练的内存。如果你有兴趣了解更多有关推理计算需求的信息,请查看 这篇深入介绍推理的精彩博文。现在,我们要开始训练了!

训练

除了模型权重之外,训练还需要在设备内存中存储优化器状态和梯度。这就是为什么当你问 “我需要多少内存来运行模型?”,别人会立即回答 “这取决于是训练还是推理”。训练总是比推理需要更多的内存,通常多得多!

模型权重

首先,可以使用纯 fp32 或纯 fp16 训练模型:

  • 纯 fp32,\(\text {模型内存}=4 \text { 字节} /\text {参数} \cdot \text {参数量}\)
  • 纯 fp16,\(\text {模型内存}=2 \text { 字节} /\text {参数} \cdot \text {参数量}\)

除了推理中讨论的常见模型权重数据类型外,训练还引入了 混合精度 训练,例如 AMP。该技术寻求在保持收敛性的同时最大化 GPU 张量核的吞吐量。现代 DL 训练领域经常使用混合精度训练,因为: 1) fp32 训练稳定,但内存开销高且不能利用到 NVIDIA GPU 张量核、2) fp16 训练稳定但难以收敛。更多混合精度训练相关的内容,我们建议阅读 tunib-ai 的 notebook。请注意,混合精度要求模型的 fp16/bf16 和 fp32 版本都存储在内存中,而模型需要的内存如下:

  • 混合精度 (fp16/bf16 + fp32), \(\text {模型内存}=2 \text { 字节} /\text {参数} \cdot \text {参数量}\)

正如上面所讲,这个仅仅是模型内存,还需要额外加上 \(4 \text { 字节 / 参数} \cdot \text {参数量}\)用于优化器状态计算 的模型副本,我们会在下面的 优化器状态 一节中算进去。

优化器状态

Adam 有奇效,但内存效率非常低。除了要求你有模型权重和梯度外,你还需要额外保留三个梯度参数。因此,

  • 对于纯 AdamW,\(\text {优化器内存}=12 \text { 字节}/\text {参数}\cdot \text {参数量}\)

    • fp32 主权重: 4 字节 / 参数
    • 动量 (momentum): 4 字节 / 参数
    • 方差 (variance): 4 字节 / 参数
  • 对于像 bitsandbytes 这样的 8 位优化器,\(\text {优化器内存} =6 \text { 字节} /\text {参数} \cdot \text {参数量}\)

    • fp32 主权重: 4 字节 / 参数
    • 动量: 1 字节 / 参数
    • 方差: 1 字节 / 参数
  • 对于含动量的类 SGD 优化器,\(\text {优化器内存} =8 \text { 字节} /\text {参数} \cdot \text {参数量}\)

    • fp32 主权重: 4 字节 / 参数
    • 动量: 4 字节 / 参数

梯度

梯度可以存储为 fp32 或 fp16 (请注意,梯度数据类型通常与模型数据类型匹配。因此,我们可以看到在 fp16 混合精度训练中,梯度数据类型为 fp16),因此它们对内存开销的贡献为:

  • 对于 fp32,\(\text {梯度内存} = 4 \text { 字节} /\text {参数} \cdot \text {参数量}\)
  • 对于 fp16,\(\text {梯度内存} = 2 \text { 字节} /\text {参数} \cdot \text {参数量}\)

激活和 Batch Size

对于 LLM 训练而言,现代 GPU 通常受限于内存瓶颈,而不是算力。因此,激活重计算 (activation recomputation,或称为激活检查点 (activation checkpointing) ) 就成为一种非常流行的以计算换内存的方法。激活重计算 / 检查点主要的做法是重新计算某些层的激活而不把它们存在 GPU 内存中,从而减少内存的使用量。内存的减少量取决于我们选择清除哪些层的激活。举个例子,Megatron 的选择性重计算方案的效果如下图所示:

激活内存

图中,红色虚线表示 A100-80GB GPU 的内存容量,“present work” 表示使用选择性激活重计算后的内存需求。请参阅 Reducing Activation Recomputation in Large Transformer Models 一文,了解更多详细信息以及下述公式的推导过程。

下面给出存储 transformer 模型激活所需内存的基本公式:

\[\begin {align*}\text {无重计算的激活内存}=sbhL (10+\frac {24}{t}+5\frac {a \cdot s}{h\cdot t}) \text { 字节}\end {align*} \]

\[\begin {align*}\text {选择性重计算的激活内存}=sbhL (10+\frac {24}{t}) \text { 字节}\end {align*} \]

\[\begin {align*}\text {全部重计算的激活内存}=2 \cdot sbhL \text { 字节}\end {align*} \]

其中:

  • \(s\) 是序列长度,即序列中词元的个数
  • \(b\) 是每个 GPU 的 batch size
  • \(h\) 是每个 transformer 层的隐含维度
  • \(L\) 是 transformer 模型的层数
  • \(a\) 是 transformer 模型中注意力头 (attention heads) 的个数
  • \(t\) 是张量并行度 (如果无张量并行,则为 1)
  • 我们假设没有使用序列并行
  • 我们假设激活数据类型为 fp16

由于重计算的引入也会引起计算成本的增加,具体增加多少取决于选择了多少层进行重计算,但其上界为所有层都额外多了一次前向传播,因此,更新后的前向传播计算成本如下:

\[2PD\leq C_{\text {forward}}\leq4PD \]

训练总内存

至此,我们得到了回答 “这个模型是否适合训练” 这一问题的一个很好的估算公式:

\[\begin {align*}\text {训练总内存} = \text {模型内存}+ \text {优化器内存}+ \text {激活内存}+ \text {梯度内存}\end {align*} \]

分布式训练

分片优化器 (sharded optimizer)

巨大的优化器内存开销促使大家设计和实现了分片优化器,目前常用的分片优化器实现有 ZeRO 和 FSDP。该分片策略可以使单 GPU 的优化器内存开销随 \(\text {GPU 个数}\) 线性下降,这就是为什么你会发现某个模型及其训练配置可能在大规模集群上能跑,但到小规模集群时就 OOM (Out Of Memory,内存耗尽) 了。下图来自于 ZeRO 论文,它形象地说明了不同的 ZeRO 阶段及它们之间的区别 (注意 \(P_{os}\)\(P_{os+g }\)\(P_{os+g+p}\) 通常分别表示为 ZeRO-1、ZeRO-2、ZeRO-3。ZeRO-0 通常表示 “禁用 ZeRO”):

ZeRO illustration

ZeRO legend

下面,我们总结一下 ZeRO 各阶段的内存开销公式 (假定我们使用混合精度及 Adam 优化器):

  • 对于 ZeRO-1,

\[\begin {align*}\text {训练总内存} \approx \text {模型内存}+\frac {\text {优化器内存}}{\text {GPU 数}}+\text {激活内存}+\text {梯度内存}\end {align*} \]

  • 对于 ZeRO-2,

\[\begin {align*}\text {训练总内存} \approx\text {模型内存}+\text {激活内存}+\frac {\text {优化器内存}+\text {梯度内存}}{\text {GPU 数}}\end {align*} \]

  • 对于 ZeRO-3,

\[\begin {align*}\text {训练总内存} \approx \text {激活内存}+\frac {\text {模型内存}+\text {优化器内存}+\text {梯度内存}}{\text {GPU 数}} + \text {(ZeRO-3 实时参数量)}\end {align*} \]

其中,在训练过程没有使用流水线并行或张量并行的条件下,\(\text {GPU 数}\) 即为 \(\text {DP 并行度}\)。更多详细信息,请参阅 Sharded Optimizers + 3D Parallelism 一文。

请注意,ZeRO-3 引入了一组实时参数。这是因为 ZeRO-3 引入了一组配置项 ( stage3_max_live_parameters, stage3_max_reuse_distance, stage3_prefetch_bucket_size, stage3_param_persistence_threshold) 来控制同一时刻 GPU 内存中可以放多少参数 (较大的值占内存更多但需要的通信更少)。这些参数会对总的 GPU 内存使用量产生重大影响。

请注意,ZeRO 还可以通过 ZeRO-R 在数据并行 rank 间划分激活,这样 \(\text {激活内存}\) 还可以再除以张量并行度 \(t\)。更详细的信息,请参阅相关的 ZeRO 论文 及其 配置选项 (注意,在 GPT-NeoX 中,相应的配置标志为 partition_activations)。如果你正在训练一个大模型,激活放不下内存而成为一个瓶颈,你可以使用这个方法用通信换内存。把 ZeRO-R 与 ZeRO-1 结合使用时,内存消耗如下:

\[\begin {align*}\text {训练总内存}\approx\text {模型内存}+\frac {\text {优化器内存}}{\text {GPU 数}}+\frac {\text {激活内存}}{\text {张量并行度}}+\text {梯度内存}\end {align*} \]

3D 并行

LLM 主要有 3 种并行方式:

数据并行: 在多个模型副本间拆分数据

流水线或张量 / 模型并行: 在各 GPU 之间拆分模型参数,因此需要大量的通信开销。它们的内存开销大约是:

\[\begin {align*}\text {并行后模型内存}\approx\frac {\text {模型内存}}{\text {流水线并行度}\times\text {张量并行度}}\end {align*} \]

\[\begin {align*}\text {并行后梯度内存}\approx\frac {\text {梯度内存}}{\text {流水线并行度}}\end {align*} \]

请注意,这是个近似公式,因为 (1) 流水线并行对降低激活的内存需求没有帮助、(2) 流水线并行要求所有 GPU 存储所有正在进行的 micro batch 的激活,这对大模型很重要、(3) GPU 需要临时存储并行方案所需的额外通信缓冲区。

分片优化器 + 3D 并行

当 ZeRO 与张量并行、流水线并行结合时,由此产生的 GPU 间的并行策略如下:

3D 并行

值得一提的是,数据并行度对于计算训练的全局 batch size 至关重要。数据并行度取决于你想在训练集群中保持几份完整模型副本:

\[\begin {align*}\text {数据并行度 = }\frac {\text {GPU 数}}{\text {流水线并行度}\times\text {张量并行度}}\end {align*} \]

虽然流水线并行和张量并行与所有 ZeRO 阶段都兼容 (例如,张量并行叠加上 ZeRO-3 后,我们会首先对张量进行切片,然后在每个张量并行单元中应用 ZeRO-3),但只有 ZeRO-1 与张量和 / 或流水线并行相结合时会效果才会好。这是由于梯度划分在不同并行策略间会有冲突 (如流水线并行和 ZeRO-2 都会对梯度进行划分),这会显著增加通信开销。

把所有东西打包到一起,我们可以得到一个典型的 3D 并行 + ZeRO-1 + 激活分区 方案:

\[\begin {align*}\text {训练总内存} \approx\frac {\text {模型内存}}{\text {流水线并行度}\times\text {张量并行度}}+\frac {\text {优化器内存}}{\text {GPU 数}}+\frac {\text {激活内存}}{\text {张量并行度}}+\frac {\text {梯度内存}}{\text {流水线并行度}}\end {align*} \]

总结

EleutherAI 的工程师经常使用上述估算方法来高效规划、调试分布式模型训练。我们希望澄清这些经常被忽视的但很有用的实现细节,如果你想与我们讨论或认为我们错过了一些好的方法,欢迎你通过 contact@eleuther.ai 联系我们!

请使用如下格式引用本文:

@misc {transformer-math-eleutherai,
  title = {Transformer Math 101},
  author = {Anthony, Quentin and Biderman, Stella and Schoelkopf, Hailey},
  howpublished = \url {blog.eleuther.ai/},
  year = {2023}
}

英文原文: http://blog.eleuther.ai/transformer-math/

原文作者: Quentin Anthony,Stella Biderman,Hailey Schoelkopf,作者均来自 EleutherAI

译者: Matrix Yao (姚伟峰),英特尔深度学习工程师,工作方向为 transformer-family 模型在各模态数据上的应用及大规模模型的训练推理。

审校/排版: zhongdongy (阿东)

本文转载于网络 如有侵权请联系删除

相关文章

  • Timer时间控件

    大家好,又见面了,我是你们的朋友全栈君。第一步、创建一个Windows窗体,第二步、创建样式,在工具箱中找到TextBox和Labell、Button、timer。第三步、改变属性的Name和Text(就是改写名称)第四步、排版按钮1:使用的控制器是Label;name改为lblTime 2:使用的控制器是TextBox;Name改为txtTime 3:使用的控制器是Button;Name改为btnGet 4.使用的控制器是Button;Name改为btnStop属性改变为第五步是获取当前时间的代码,那么我们就有写一个方法,定义一个时间的变量DateTimeprivatevoidGetTime(){ stringtime=DateTime.Now.ToShortDateString()+”“+DateTime.Now.ToLongTimeString();//定义一个事件this.txtTime.Text=time;//利用this把获取当前系统时间绑定到文本框}第六步:写“获取当前系统时间”按钮的代码privatevoidbtnGet_Click(objectsender,Event

  • 横跨Java后端开发技术栈,高质量通关SpringBoot

    当技术抛弃你时甚至不会跟你说声再见“疯狂系列”长期以来一直是博文菌心尖尖上的肉,配套书籍一出版即跃居京东计算机类TOP1,好评度高达98%!今天推荐的这门课,它就是《跟着李刚老师学SpringBoot终极课程体系》之一的——《跟着李刚老师学SpringBoot》SpringBoot作为Java后端开发集大成的框架,它几乎无所不能。这套视频课程一共129集,每集20~30分钟,与阅读SpringBoot官方手册不同本课程制定了一条切实可行的学习曲线,你只需具有基本的SSH、SSM基础,不用掌握其他框架或技术的知识,跟着学习,就能真正掌握SpringBoot!你能想到的所有相关技术,这里基本都有!废话不多说,直接上图:(上下滑动查看完整目录)▼扫码了解课程详情▼等等!别着急!原价168元的SpringBoot技术课打包出手,享钜惠福利最后两单,限时239元横跨Java后端开发技术栈 ▋超值进阶:一站横跨Java后端开发技术栈只要顺着SpringBoot所整合的各种技术进行学习,一旦真正掌握了SpringBoot所能整合的各种技术,基本上也就掌握了Java后端开发的绝大部分技术!《跟着李刚老

  • 让用户依次输入三个整数,求出三个数中的最小值,并打印到控制台

    让用户依次输入三个整数,求出三个数中的最小值,并打印到控制台//导包 importjava.util.Scanner; publicclassTest{ publicstaticvoidmain(String[]args){ //让用户依次录入三个整数,求出三个数中的最小值,并打印到控制台。 //创建键盘输入对象 Scannerscan=newScanner(System.in); //依次输入三个数 System.out.print("请输入第一个数:"); inta=scan.nextInt(); System.out.print("请输入第二个数:"); intb=scan.nextInt(); System.out.print("请输入第三个数:"); intc=scan.nextInt(); //定义一个整数用来存储最小值 intminimum; //对三个数进行判断 if(a>b&&b>c){ minimum=c; }elseif(a>c&&c>b){ m

  • RecyclerView实现纵向和横向滚动

    为方便自己以后学习,自己记录学习,大家也可以参考,有什么问题一起探讨。今天学习RecyclerView,下边来说一下实现数据垂直滚动和数据横向滚动。先上图为敬:所用工具:AndroidStudio纵向滚动1、添加依赖库:打开app/build.gradle文件,在dependencies闭包中添加如下内容(compile‘com.android.support:recyclerview-v7:24.2.1’为添加的内容)dependencies{ compilefileTree(dir:'libs',include:['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2',{ excludegroup:'com.android.support',module:'support-annotations' }) compile'com.android.support:a

  • 数据分析基础——EXCEL快速上手秘籍

    作者|周志鹏来源|数据不吹牛EXCEL从入门到熟练?缺乏体系和数据源?练好这篇就够了!这篇文章是本系列的第一篇,选择性汇总了EXCEL的常用且重点的模块和公式,用作内部员工EXCEL基础操作培训,以帮助表格基础薄弱的同事快速熟悉常用操作,提升工作效率。现将内容分享,作为数据分析基础的第一篇。所有公式均结合实例(本节课以小例子为主),讲为辅,练为主,实例数据附在文章最后,也可在公众号导航栏“实战数据”获取。陈独秀(基础扎实)童鞋可以直接跳过,其他同鞋可以当做回顾和复习。这,将是后面数据分析的公式(EXCEL)基础(下一篇将会是实战篇)。文章略长,大家可以先马后看,当然更重要的是实践。P1基础操作模块:1.1、数据透视表:开篇神器必谈透视表,它可以说是EXCEL的核武器了,杀伤力爆表。不过有一点和核武器不同,它不仅灰常重要,还经常在实战中使用。百度定义是这样的:数据透视表(PivotTable)是一种交互式的表,可以进行某些计算,如求和与计数等。Emmm,各位看完之后有没有一个特别清晰的概念呢。反正我是没有的。我觉得数据透视表就是一个快速分组,并基于分组个性化计算的神器。下面我们结合数据来

  • 使用Anaconda 环境安装 TensorFlow

    AnacondaTensorFlow按照以下步骤在Anaconda环境中安装TensorFlow:1.按照Anaconda下载网站上的说明下载并安装Anaconda2.调用以下命令创建名为tensorflow的conda环境C:>condacreate-ntensorflowpippython=3.5复制3.发出以下命令以激活conda环境C:>activatetensorflow (tensorflow)C:>#Yourpromptshouldchange复制4.发出相关命令以在conda环境中安装TensorFlow要安装仅支持CPU的TensorFlow版本,请输入以下命令(tensorflow)C:>pipinstall--ignore-installed--upgradetensorflow复制要安装GPU版本的TensorFlow,请输入以下命令(在同一行):(tensorflow)C:>pipinstall--ignore-installed--upgradetensorflow-gpu复制5.验证您的安装启动终端如果您是通过Anaconda

  • 隔舱模式

    将应用程序的元素隔离到池中,这样,如果一个元素发生故障,其他元素可继续工作。此模式之所以称为“隔舱”(Bulkhead),是因为它类似于船体的分段区。如果船体受到破坏,只有受损的分段才会进水,从而可以防止船只下沉。上下文和问题基于云的应用程序可以包含多个服务,其中每个服务具有一个或多个使用者。服务过载或发生故障会影响服务的所有使用者。此外,一个使用者可以使用每个请求的资源同时向多个服务发送请求。当使用者向配置不当或无响应的服务发送请求时,可能无法及时释放客户端请求所用的资源。随着不断地向服务发送请求,这些资源可能会耗尽。例如,客户端的连接池可能会耗尽。此时,使用者向其他服务发出的请求会受到影响。最终,使用者不再能够向其他服务(而不仅仅是原始的无响应服务)发送请求。资源耗尽问题同样会影响具有多个使用者的服务。源自一个客户端的大量请求可能耗尽服务中的可用资源。其他使用者不再能够使用该服务,从而导致连锁故障效应。解决方案根据使用者负载和可用性要求,将服务实例分区成不同的组。此设计有助于隔离故障,即使在发生故障期间,也能为某些使用者保留服务功能。使用者也可以将资源分区,确保用于调用一个服务的资

  • minigui:mgplus交叉编译警告 include locationi

    版权声明:本文为博主原创文章,转载请注明源地址。https://blog.csdn.net/10km/article/details/83088803今天在交叉编译mingui的mgplus组件库时输出了一个警告:mips-linux-gnu-g++-DHAVE_CONFIG_H-I.-I../..-D__MGPLUS_LIB__-I..-I../agg -I../../include-I../agg/font_freetype-ffunction-sections-fdata-sections -I/home/gyd/workspace/app/dependencies/release/freetype-2.6.1/mips-linux-gnu/include/freetype2 -I/home/gyd/workspace/app/dependencies/release/libpng-1.2.59/mips-linux-gnu/include/libpng12 -I/home/gyd/workspace/app/dependencies/release/zlib-1.2.11/mi

  • 转载:Package by feature, not layer

    原文地址:Packagebyfeature,notlayerPackagebyfeature,notlayerThefirstquestioninbuildinganapplicationis"HowdoIdivideitupintopackages?".Fortypicalbusinessapplications,thereseemstobetwowaysofansweringthisquestion.软件开发首先要处理的事情包括对package进行划分 PackageByFeaturePackage-by-featureusespackagestoreflectthefeatureset.Ittriestoplaceallitemsrelatedtoasinglefeature(andonlythatfeature)intoasingledirectory/package.Thisresultsinpackageswithhighcohesionandhighmodularity,andwithminimalcouplingbetweenpackages.Ite

  • Tomcat介绍,安装jdk,安装Tomcat

    Tomcat介绍:安装jdk:jdk版本1.6,1.7,1.8       =以后其他程序员说了版本号678 其实就是1.6,1.7,1.8 版本  官网下载地址http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html   =需要先下载到Windows上面       --下载完成以后可以使用命令sz,rz把Windows的数据包传送到Linux上面            --或者使用Xftp区分系统下载jdk8,放到/usr/local/src/目录下     =今天usl/local/src/目录然后把下载的数据包传送到里面来tarzxvfjdk-8u144-linux-x64.tar.gz     =解压下载的数据包mvjdk1.8.0_144/usr/local/jdk1.8         =给解压完成后的数据包更换一个其他目录并且改名vi/etc/profile//最后面增加        =编辑/etc/profile 环境变量文件#环境变量配置文件 JAVA_H

  • 华为狼VS腾讯企鹅,解读两大巨头的大数据体系

    菜鸟顺丰的数据之战刚刚平息,华为腾讯两大巨头又因为用户数据之争”大打出手“,因华为荣耀Magic手机出现的可根据微信聊天内容自动加载信息功能,腾讯向监管部门投诉,指其侵犯腾讯及用户的数据。微信作为一款国民级应用,拥有着近10亿的用户,在这个数据为王的时代,微信的庞大用户数据无疑是一座巨大的金矿,无论硬件商还是软件商都对这块巨大的蛋糕垂涎,不难解释在华为对腾讯公开宣战之后,包括支付宝、科大讯飞在内的一众互联网应用都积极的参与华为合作,数据价值的吸引,让各大商家趋之若鹜。本文分析了华为和腾讯的大数据体系,钱塘大数据公众号后台回复“华为”,获取本文PPT。华为大数据——让数据慧说话早在2007年,华为就已经开始投入大数据产品研发。在大数据研发上始终保持1500+的人员规模,在全球13个开放实验室,与各国200多家合作伙伴进行大数据方案的联合创新,并拥有500多项技术专利。 基于自身大数据平台强大的数据分析能力和建模工具,华为提供了城市大数据、精准扶贫、金融风险监控、智慧交通等大数据解决方案。在大数据领域,2015-2016年华为在Hadoop社区贡献排名全球第三,Spark社区贡献排名全球第

  • 深度学习领域四个不可不知的重大突破

    作者|SethWeidman译者|大愚若智编辑|Emily为何阅读本文?无论该领域中的从业者,或是企业组织,为了运用深度学习技术,首先需要做好两个准备:“能做什么”:了解深度学习领域的最新进展能够用来做什么。“怎么做”:训练新模型,或将现有模型用于生产环境的技术能力。在开源社区的努力下,第二个问题正变得越来越容易。目前已经有大量优秀的教程在告诉大家,如何使用诸如TensorFlow等库训练并使用深度学习模型,很多教程甚至每周都会发布新的内容,例如TowardsDataScience。因此一旦你明确了自己打算如何使用深度学习技术,那么就可以努力让想法变为现实,虽然这一过程不那么简单,但只需要进行标准化的“开发”工作,例如按照本文介绍的各种教程按图索骥,结合自己的特定用途和/或数据进行修改,根据大家在StackOverflow等网站进行的讨论进行排错,这就可以实现了。这也可以避免很多麻烦的事情,例如并不需要成为(或者雇佣)能够从零开始自行开发神经网络的专家,而且还必须同时具备娴熟的软件工程经验。这一系列随笔会试图解答上文提出的第一个问题:从较高层面概括谈谈深度学习技术到底能够做些什么,同时

  • 使用 NoSQL 数据库分析大规模数据

    本文转自IBM的developerWorks,主题是关于使用NoSQL存储和处理大规模数据,文章列举了一些循序渐进的学习资料,包括了视频音频和文字材料,是一个很不错的了解、学习NoSQL的知识向导。RDBMS模型是传统C/S模式存储数据的重要基础,但是它无法实现以简单且低廉的方式进行扩展。而目前,更多的应用需求是像Facebook和Twitter一样需要拥有很强的可扩展性,所以,无模式的存储模型–NoSQL应运而生,提供了相应的解决方案。本学习路线图向Java开发人员介绍了NoSQL技术,以及ApacheHadoopMapReduce技术在处理大规模数据方面的优势。1.NoSQL入门NoSQL数据库被更多的人所关注是因为它在解决大规模数据的可扩展性上有它独到的解决方案。无模式的数据存储模型与传统的关系型数据库有着本质上的区别,但是它们并不像想象中那么难以使用。阅读:Java开发2.0:NoSQL2.流行NoSQL数据库实用指南现在,您已经对NoSQL有了一些基本的认识,是时候去认识一些目前流行的数据库了。学习针对MongoDB、CouchDB、Amazon的SimpleDB和Googl

  • IO流

    一、流的基本分类 1.操作数据单位:字节流、字符流 2.数据的流向:输入流、输出流 3.流的角色:节点流、处理流   二、流的体系结构 抽象基类                 节点流(或文件流)              缓冲流(处理流的一种)      转换流 InputStream               FileInputStream          &

  • centos7 一键安装openstack 方法

      折腾了好久,一直没有成功安装过openstack,心里总是不甘心。无意中看到一篇文档,试了一下,成功了。下面就记录一下曾经的操作。   【安装环境】IBMX220i笔记本电脑 酷睿i3+8G内存+500G硬盘            看网上介绍的,通过vmware虚拟机的方式进行安装,我没有测试过,不过,我在virtualbox上测试安装,总是失败,不知道是内存不足,还是硬盘不足,或者是其他问题,总之都是失败,不再试验了。下面就说说在物理机上的安装步骤   【安装步骤】 第一步、在centos官网,下载centos7-minimal版本。        我下载的是:CentOS-7-x86_64-Minimal-1908(1).iso   第二步、通过U盘,制作安装盘,使用rufus。 第三步、安装到IBMX220i系统中。    &nb

  • 【转】 Tornado + Ajax 实现页面内刷新

     原文链接:https://blog.csdn.net/tsing1996/article/details/73740426     需要的环境 jquery-3.2.1.min.js(从jQuery官网下载http://jquery.com/download/) simplejson(pipinstallsimplejson) 简单的例子,从第一个输入框里输入一段文本,点击按钮实现将第一个框内的值传递到第二个框中   test.html 复制 <!DOCTYPEhtml> <html> <head> <title></title> </head> <body> <inputtype="text"id="na"/> <inputtype="button"value="click"onclick="DoAjax();"/>{#点击按钮调用DoAjax方法#} <inputtype="text"id="nb"/> <

  • 程序员中的长期主义者

    利益面前保护自己,试着用技术保护自己   提代码时写好注释commit-m干了什么事,别人看了注释很专业   用脚本跑一下,列出哪一天干了什么事就是季度工作量,足够堵住那些嘴炮 心里建设   《黑客与画家》艺术家不会觉得自己智商有问题。如今的大神程序员曾今也多次觉得自己智商堪忧,所以“你并不孤独”。   我具备一些互联网思维,并且互联网思维不是那么反人性,随着理解能力的逐步提高,对此不那么痛苦。   我并不具备计算机思维,计算机思维本来就不是一个很好的类比,有极强的误导性,一个正常人去思考计算机会很痛苦。换句话说计算机没有思维只有抽象和接受,所以就是反复弄,习惯就好,相信我“你并不孤独”。(寻找老司机获得套路,然后快速入门,然后不断学实践新的东西和打基础) 大纲   用互联网、计算机思维解决问题   学新东西   夯实基础     数据结构算法、操作系统、计算机网络、编译原理、数据结构和算法     case       vue源码   1、不频繁地执行函数   防抖debounce/节流throttle,区别前者执行时间点可能会不断更新 2、promise   手撸一个pr

  • LA 4329 ping-pong树状数组

    题目链接:   刘汝佳,大白书,P197. 枚举裁判的位置,当裁判为i时,可以有多少种选法,如果已经知道在位置i之前有ci个数比ai小,那么在位置i之前就有i-1-ci个数比ai大。 在位置i之后有di个数比ai小,那么在位置i之后就有n-i-di个数比ai大。 这样,选法数有ci*(n-i-di)+di*(i-1-ci). 注意到ai的值各不相同且ai的值最大不超过10^5,那样就可以用v[a[i]]表示a[i]是否已经存在,这样当顺时针扫描的时候,每次更新v[a[i]]=1;//表示已经存在。 比ai小的数的个数就是sum(v[j])j<a[i]. 至于d[i]的求法逆着扫描即可,如果用树状数组加速。 贴代码: 1#include<cstdio> 2#include<cstring> 3#include<iostream> 4usingnamespacestd; 5typedeflonglongintll; 6constintN1=20004,N2=100005; 7inta[N1],c[N2],sum[N1]; 8intlo

  • [工具教程] HBuilder调试夜神安卓模拟器方法(该方法真实有效)

    HBuilder调试夜神安卓模拟器方法 现在开发手机app的IDE很多,今天我就以我个人开发使用的HBuider开发工具讲一下手机app开发调试。HBuider支持真机调试,这个比较简单,只要安装好手机的驱动,把手机和电脑通过数据线连接就可以调试发布了,如果手机连接不上,可以在电脑和手机上都安装360手机助手基本上就可以了。今天重点说一下使用夜神安卓模拟器和HBuider的连接调试方法。第一步:下载安装夜神模拟器,这个在百度搜索就可以找官网,下载安装就可以了。第二步:查找已经安装的夜神模拟的端口,这里说一下夜神模拟器默认端口是62001,但是有些版本可能不是这个端口,怎么查找到底是哪个端口呢?按照如下顺序进行就可以查找到你按装的夜神模拟器端口了。1.打开夜神模拟器,确保正常启动后,出现安卓桌面。2.打开夜神模拟器的安装文件夹,找到D:\YS\Nox\bin文件夹打开(D:\YS是夜神模拟器安装的路径根目录),找到【debugReport.bat】文件,双击启动该批处理文件。会显示如下图:noxadbport:52001alreadyconnectedto127.0.0.1:52001

  • python模块-pymysql源码分析及其常见使用

    D:\soft\python36\Lib\site-packages\pymysql>tree/f 卷新加卷的文件夹PATH列表 卷序列号为960E-961E D:. │charset.py │connections.py │converters.py │cursors.py │err.py │optionfile.py │protocol.py │times.py │util.py │_auth.py │_compat.py │_socketio.py │__init__.py │ ├─constants ││CLIENT.py ││COMMAND.py ││CR.py ││ER.py ││FIELD_TYPE.py ││FLAG.py ││SERVER_STATUS.py ││__init__.py ││ │└─__pycache__ │CLIENT.cpython-36.pyc │COMMAND.cpython-36.pyc │CR.cpython-36.pyc │ER.cpython-36.pyc │FIELD_TYPE.cpython-36.pyc │FLAG.cp

  • 一点思路

      1.发图片邮件,通过图片请求直接拿UA和refer。

相关推荐

推荐阅读