844 Matching Annotations
  1. Dec 2023
    1. 论文还提到了开源 LLM 与 ChatGPT 之间的差距。之前的评估(如 AlpacaEval)没有为每个测试样本设置标签,因此很难进行大规模的详细分析。研究者观察到开源 LLM 在多个任务和主题上与 OpenAI GPT 仍有差距。很明显,GPT 在几乎所有任务和主题上的表现都更为均衡。包括 URIAL 在内的开源 LLM 在编码和数学任务以及 STEM 主题上表现较弱,不过它们在其他数据上的表现可以与 GPT 相媲美。

      [!NOTE] ICL 在常规对齐中能否匹敌 SFT?代码/数学领域呢?

      flashcard

      常规对齐似乎可以 代码/数学不行

  2. Nov 2023
    1. The examples above show how to download from a model repository. To download a dataset or a Space, use the --repo-type option:

      [!NOTE] 使用 huggingface-cli download 下载非模型文件时,需要注意什么?

      flashcard

      需要指定 --repo-type

    1. 实际上,即使我们将延迟降到微秒级,许多应用也无法充分利用这个低延迟。其中一个原因是延迟隐藏问题。当我们等待这些微秒级事件时,比如进行网络通信或者存储设备的读写,CPU 应该去执行什么操作?在传统的计算机体系结构中,CPU 的流水线能很好地隐藏纳秒级事件。也就是说,在等待这些事件时,CPU 可以执行其他指令,而不需要软件干预。然而,对于微秒级时延的事件,CPU 的流水线深度不足以隐藏时延,因此 CPU 就会卡住等待这个慢速的指令,其效率是很低下的。对于毫秒级事件,操作系统可以处理这些任务切换,这是软件的职责。操作系统在进行进程或线程切换时,只需几个微秒就能完成,因此不会浪费太多时间。但是,如果事件本身就是微秒级的,比如访问存储花费 10 微秒或访问高速网络花费 3 微秒,这时候如果将 CPU 核切换到其他进程或者线程上,操作系统本身就要花费几个微秒的时间。操作系统切换到其他进程或者线程,再切换回来,这个过程花费的时间可能比直接等待事件完成还要长。所以,对于微秒级的时延,操作系统的任务切换实际上是在浪费时间。体系结构和操作系统的机制都不能隐藏微秒级的时延,而如今最先进的网络和存储硬件时延都降到了微秒级,这就是微秒级时间隐藏难题的原因。

      [!NOTE] 计算机系统中,微秒级时延隐藏为什么困难?

      flashcard

      • CPU 的延迟是纳秒级很难找到足够指令隐藏微秒级事件
      • OS 任务切换的延迟是微秒级,用于隐藏微秒级事件得不偿失
    1. 先去找有没有作者做的slides,有slides就优先结合slides读

      [!NOTE] 有什么比 paper 更好的阅读材料?

      flashcard

      作者制作的 slides?

    2. 分工合作,找到对的人(co-author)做对的事。in other word,如果有个子任务你知道XXX特别擅长能在一天内给你干出来而你自己整得一周,那就尝试拉他入队伍,然后把这个子任务分给他。这样构成了一个共赢的局面:合作者用最小的力气节约了你大量时间,这样合作者往往也更愿意帮忙。至于找不到人的事情就别逃避,留给自己做。

      [!NOTE] 如何给其他人分配任务?

      flashcard

      找擅长的人做擅长的事

    3. 作为project leader,要提前figure out 一些composable immediate milestones。这些milestone一定一开始要比较容易,i.e., actionable,因为前期正反馈很重要。

      [!NOTE] 开启项目时,对于阶段性目标,可以怎么做?

      flashcard

      提前设置一些可供对比的阶段性目标,形成正反馈

    1. 在第二阶段预训练中,我们仔细调整了数据配比,原因如上所述,我们希望赋予模型解题能力的同时,更小程度的破坏其通用能力上的效果。最终第二阶段预训练中20%来自Skypile-STEM,80%来自Skypile-MAIN避免灾难性遗忘。我们尝试了从10%到40%的Skypile-STEM数据权重,发现20%的占比可以维持验证集损失不上升的同时,benchmark指标能有提升。

      [!NOTE] Continual Training 中,如何设置数据配比?

      flashcard

      少部分新数据,大部分原数据?

    2. 为了验证In-domain数据训练对模型训练的影响,我们将训练500B token后的模型直接使用Skypile-STEM数据继续训练1B token,可以看到主流的benchmark上CEVAL和GSM8K得分均大幅上涨,但在中英领域验证损失上则出现了明显的上升。表明通过In-domain数据的训练,模型做题能力和刷榜能力会大幅提升,但其通用能力是大幅下降的。

      [!NOTE] Benchmark In-domain 数据训练对模型能力具体会有什么影响?

      flashcard

      通过In-domain数据的训练,模型做题能力和刷榜能力会大幅提升,但其通用能力是大幅下降的

    3. Benchmark的问题就更加严重了,第一是因为benchmark是公开数据,非常容易针对,通过In-domain数据的训练即可增强对应benchmark上的效果,但模型的能力并不一定强。此外Benchmark评估一般是准确率,准确率是一个不连续的指标(对大模型涌现的解释),可能训练500B token,benchmark上的指标都没有任何变化,因此我们无法根据benckmark上的准确率推测持续当前训练模型会达到一个什么样的效果。Benckmark评估具有一定的波动性&可操作性,不同Prompt选择和答案提取方式会对结果产生很大的影响,

      [!NOTE] Benchmark 评估有哪些问题?

      flashcard

      1. 容易针对
      2. 粒度太粗,不连续
      3. 波动性大
    4. 在训练过程中常见操作是上采样一些高质量数据,比如Llama1的训练中会上采样book来源的信息

      [!NOTE] 预训练中可能会如何提高高质量数据占比?

      flashcard

      上采样一些高质量数据

    5. Training loss因为数据配比的原因是一个整体的指标,并且不同模型不能相互比较,比如A模型的代码占比20%,B模型的代码占比10%,那么A模型训练同样token数下训练Loss会显著低于B模型,因为代码数据中有很多可以预测的结构,因此loss相对更低。不同模型是无法直接比较Training loss来对比效果的。

      [!NOTE] training loss 为什么不能相互比较?

      flashcard

      因为与数据配比有关

    6. 因为模型训练的global batch size更大,我们将学习率设置为Llama2-13B的两倍,这样可以保证训练时梯度的方差是一致的。

      [!NOTE] 学习率相对 batch size 以平方根增长,有什么好处?

      flashcard

      保证训练时梯度的方差一致

    7. 根据我们的前期实验,在更大batch size的训练下,更加瘦长的网络具备更好的泛化性能。因此我们将层数增加到52层,同时缩减了隐藏层大小,使得总体参数量和Llama2-13B模型是相当的。

      [!NOTE] (预训练中)batch size 更大时,什么样的模型结果具有更好的泛化性能?

      flashcard

      Skywork: 瘦长

    8. Llama2-13B的训练效率,即1750 tokens / per gpu / per second

      [!NOTE] LLaMA-13B 预训练的效率是?

      flashcard

      1750 tokens / per gpu / per second

    9. 为什么大体上沿用Llama的结构?Llama结构主要有三个特点:1. 使用RMSNorm代替传统的Layernorm,使用pre normalization保持训练稳定性。2. 使用SwiGLU激活函数而非传统的ReLU。3. 使用相对位置编码(RoPE等)而非传统的绝对位置编码。在我们的前期实验中也验证了这一点,相比于GPT结构Llama结构可以收敛更快,收敛的效果也更好。

      [!NOTE] LLaMA 架构相比 GPT 有什么不同?效果如何?

      flashcard

      主要有三个特点:1. 使用RMSNorm代替传统的Layernorm,使用pre normalization保持训练稳定性。2. 使用SwiGLU激活函数而非传统的ReLU。3. 使用相对位置编码(RoPE等)而非传统的绝对位置编码 Skywork 前期实验证明 LLaMA 优于 GPT

    1. 目录是否有必要存在 基于路径的索引难以并行或分布式化,因为我们总是需要查到一级目录的底层编号才能查到下一级,这是一个天然串行的过程。在一些性能需求极高的环境中,可以考虑弱化目录的权限控制职能,将目录树结构扁平化,将文件系统的磁盘布局变为类键值对存储。

      [!NOTE] 基于路径/目录树的文件索引该如何优化性能?

      flashcard

      • 弱化目录的权限控制职能,将目录树结构扁平化,将文件系统的磁盘布局变为类键值对存储。
    2. 对于目录而言, Access 的 rwx 含义有所不同: r 表示是否允许获取该目录下有哪些文件和子目录; w 表示是否允许在该目录下创建/删除文件和子目录; x 表示是否允许“通过”该目录。

      [!NOTE] Linux 中,目录的 Access 字符串含义是怎样的?

      flashcard

    1. Kernel compile flags can usually be checked by looking at /proc/config.gz or /boot/config-<kernel-version>.

      [!NOTE] 如何查看 Linux 内核的编译选项?

      flashcard

      • /proc/config.gz
      • /boot/config-<kernel-version>

      Packages

    1. 获得了每个基本块的 LiveIn 和 LiveOut 集合以后,我们需要进一步地计算基本块内每个 TAC 语句的 LiveIn 和 LiveOut 集合。如果我们把基本块内所有 TAC 语句分别看成是一个独立的基本块,则不难想像,前面提到的活跃变量方程仍然有效,不同之处在于,一个基本块对应的 “控制流图” 有以下三种特点: 每个节点的出度都是 1,也就是说 LiveOut(B) = LiveIn(Succ(B))。 由于每个结点只含有一个语句,因此其 Def 集要么是空集,要么只含有一个元素。 由于每个结点对应的语句里所引用的所有变量在使用的时候都未在该基本块中经过定值,其 LiveUse 集合就是源操作数对应的所有变量。 基于上面三个特点,已经求出基本块的 LiveOut 集合的前提下我们只需要在每个基本块内从后往前遍历基本块内的指令就可以对每条基本块内指令求出 LiveIn、LiveOut。

      [!NOTE] 编译优化中,单指令构成的基本块有哪些特点?

      flashcard

      1. 每个节点的出度都是 1,也就是说 LiveOut(B) = LiveIn(Succ(B))
      2. 由于每个结点只含有一个语句,因此其 Def 集要么是空集,要么只含有一个元素
      3. 由于每个结点对应的语句里所引用的所有变量在使用的时候都未在该基本块中经过定值,其 LiveUse 集合就是源操作数对应的所有变量
    2. 一般来说,活性分析是通过求解活跃变量方程来完成的。为了介绍活跃变量方程的概念, 我们需要先引入下面四种针对基本块的集合: Def 集合:一个基本块的 Def 集合是在这个基本块内被定值的所有变量。所谓的定值 (definition),可以理解为给变量赋值,例如加法语句给目标变量定值等(注意:Store 语句不给任何变量定值,Load 语句则会给对应变量定值)。 LiveUse 集合:一个基本块的 LiveUse 集合是在这个基本块中所有在定值前就被引用过的变量,包括了在这个基本块中被引用到但是没有被定值的那些变量。 LiveIn 集合:在进入基本块入口之前必须是活跃的那些变量。 LiveOut 集合:在离开基本块出口的时候是活跃的那些变量。 其中 Def 和 LiveUse 是基本块本身的属性,对每个基本块从后往前遍历基本块内的指令便可以求出。 有了基本块的这四个集合的概念,我们给出控制流图中每个基本块满足的活跃变量方程: 该方程说的是一个基本块的 LiveOut 集合是其所有后继基本块的 LiveIn 集合的并集,而且 LiveIn 集合是 LiveUse 集合的变量加上 LiveOut 集合中去掉 Def 集合以后的部分。 这个方程的直观意义是: 一个基本块的任何一个后继基本块入口处活跃的变量在这个基本块的出口必须也是活跃的。 在一个基本块入口处需要活跃的变量是在该基本块中没有定值就被使用的变量,以及在基本块出口处活跃但是基本块中没有定值过的变量(因为它们的初值必定是在进入基本 块之前就要具有的了)。 根据这个方程,我们可以通过迭代更新的办法求出每个基本块的 LiveIn、LiveOut 集合,以下是求解的伪代码:

      [!NOTE] 编译优化中,活跃变量方程的内容是?

      flashcard

      1. 一个基本块的 LiveOut 集合是其所有后继基本块的 LiveIn 集合的并集,
      2. 而且 LiveIn 集合是 LiveUse 集合的变量加上 LiveOut 集合中去掉 Def 集合以后的部分。

      这个方程的直观意义是: 1. 一个基本块的任何一个后继基本块入口处活跃的变量在这个基本块的出口必须也是活跃的。 2. 在一个基本块入口处需要活跃的变量是在该基本块中没有定值就被使用的变量,以及在基本块出口处活跃但是基本块中没有定值过的变量(因为它们的初值必定是在进入基本 块之前就要具有的了)。

    3. 基本块的划分算法比较简单:从头到尾扫描操作序列,当遇到以下情况时结束当前基本块,并开始一个新的基本块建立过程: 当遇到一个 Label 标记而且存在跳转语句跳转到这个行号时。 当遇到 Branch、CondBranch 或者 Return 等跳转语句时。 整个操作序列扫描完毕后,我们就成功建立了所有基本块。

      [!NOTE] 如何划分基本块?

      flashcard

      看边界: 1. 可达的 label 2. 跳转指令

    4. 基本块是指一段这样的代码序列: 除出口语句外基本块中不含任何的 Branch、Beqz(条件为假时跳转)、Bnez(条件为真时跳转)或者 Return 等跳转语句(但可以包含 Call 语句)。 除入口语句外基本块中不含任何的 Label 标记,即不能跳转到基本块中间。 在满足前两条的前提下含有最多的连续语句,即基本块的头尾再纳入一条语句将会违反上面两条规则。 下面的例子中,代码中不同的基本块被标以不同的颜色: 也就是说,基本块内的代码执行过程总是从基本块入口开始,到基本块出口结束的,中间不会跳到别的地方或者从别的地方跳进来。

      [!NOTE] 编译优化中,基本块的含义是?

      flashcard

      无跳转、连续执行的最大块

    1. 通过对比 delta 参数的变化范围,作者团队首先发现,对比预训练中参数的变化范围,有监督微调下 delta 参数的变化范围往往在 0.5% 以内,这似乎表明,有监督微调不是“向大模型引入新的能力”,而是在“释放大模型本身的能力”。同时,对比 delta 参数的变化范围以及 DARE 的效果可以发现,当在 delta 参数变化范围相对较小(0.5%)时,DARE 可以维持较高的性能水平,而一旦 delta 参数发生了更大程度的变化,DARE 就有可能失效。

      [!NOTE] SFT 中,参数改变量相比预训练参数幅度有多大?

      flashcard

      通常小于 0.5%

    2. 如果记大模型原始预训练参数为,经过有监督微调后的参数为,其中上标 指不同的领域任务,我们将发生变化的参数叫做 Delta 参数,即:Delta 参数反映了模型在微调过程中的变化情况。显然,对于分析模型在有监督微调中“发生了什么”,Delta 参数显得至关重要。在过去的不少研究中,学者们已经发现,在有监督微调过程中,Delta 参数往往是大量冗余的。

      [!NOTE] SFT 中,参数的变化值有什么特点?

      flashcard

      非常稀疏

    3. 在第一幅图中,WizardLM-70B 在 AlpacaEval 数据集下当删除率为 0.9 时出现了巨幅下降,作者猜测原因可能在于这一任务比较困难,需要更多的 delta 参数才能有效的完成任务,而当删除率上升时,其删除了重要参数导致参数间的依赖关系被破坏,从而出现性能巨幅下降。

      [!NOTE] SFT 中,什么任务的 Δ 参数比较复杂?

      flashcard

      对齐任务?WizardLM-70B 在 AlpacaEval 数据集下当删除率为 0.9 时出现了巨幅下降

    4. 这种基于 DARE 的模型融合方式并不局限于某一种特定的模型融合方法,传统上的 Average Merging、Task Arithmetic、Fisher Merging、RegMean、TIES-Merging 都可以使用这一方法得到增强

      [!NOTE] Model Merging 有哪些常见的方法?

      flashcard

      Average Merging、Task Arithmetic、Fisher Merging、RegMean、TIES-Merging

    5. 最为重要的是,这种融合方式不用 GPU,不用重新训练,一切都可以在 CPU 中完成!

      [!NOTE] DARE (Drop And REscale) 在计算上有什么优点?

      flashcard

      不用 GPU,不用重新训练,一切都可以在 CPU 中完成

    6. 名为 DARE(Drop And REscale)的削减冗余参数的方法。顾名思义,Drop 和 Rescale,DARE 的思想非常简单,分两步走,首先给定一个随机的删除率 ,以 为概率随机删除 Delta 参数(置为 0),即 Drop 的过程,而后以 为概率等比例扩大剩余保留的参数,就完成了 DARE 的过程,流程图如下图所示:如果形式化的定义 DARE,即为:最终,得到后,与 相加,即 ,从而完成 DARE。在实验中,论文作者惊讶的发现,采用 DARE,可以在舍弃大量冗余参数的同时,维持模型的性能。从图中可以看到,随着 Drop rate 的上升(舍弃的参数越来越多),模型的性能仍然可以维持不错的水平。同时,模型的参数量越大,在不影响精度的情况下其最大 Drop rate 的值也在上升,甚至可以达到 99% !这意味着 DARE 可以在几乎删除 99% 的参数的基础上仍然维持模型的性能,这一发现不仅表明,有监督微调确实是如何 LoRA 那样在学习一种“低秩结构”,并且也进一步说明了Delta 参数确实是大量冗余的。

      [!NOTE] DARE(Drop And REscale)的主要结论是?

      flashcard

      以类似经典 Dropout 的方式处理 SFT 的 Δ 参数 随着 Drop rate 的上升(舍弃的参数越来越多),模型的性能仍然可以维持不错的水平。同时,模型的参数量越大,在不影响精度的情况下其最大 Drop rate 的值也在上升,甚至可以达到 99% !

    1. For large models, we recommend specifying the precision of the model using the --precision flag instead of accelerate config to have only one copy of the model in memory.

      [!NOTE] 🤗 Accelerate 中,通过 config 设置精度,可能有什么问题?

      flashcard

      内存中存在模型的重复复制

    1. Why use tensor_parallel ... v.s. DeepSpeed and FairScale DeepSpeed has many parallelization strategies, but requires careful configuration tensor_parallel has one strategy that works with 1 line of code tensor_parallel works in a jupyter notebook v.s. MegatronLM MegatronLM has great tensor parallelism for one model architecture tensor_parallel has good parallelism for any architecture tensor_parallel is way easier to install v.s. parallelformers parallelformers is inference-only, tensor_parallel supports training v.s. alpa alpa is a powerful tool for automatic distributed training / inference in JAX tensor_parallel works with PyTorch v.s. Model.parallelize() both are easy to use, both fit large models in parallelize, one GPU works at a time in tensor_parallel, GPUs work in parallel In short, use tensor_parallel for quick prototyping on a single machine. Use DeepSpeed+Megatron or alpa for million-dollar training runs.

      [!NOTE] 在小规模(一台机器)使用张量并行时,有什么好用的库?

      flashcard

      tensor_parallel

    1. 合格的耳机是三频均衡的,而不是仅突出低音的路边摊耳机;也不是缺少低频的耳机(人耳对低频不敏感,所以缺少低频的耳机太刺耳不好听)。第二种耳机伤害很大,人老了先损失的是高频辨识能力,这里就不展开说明了。(引战低端动铁,不如我动圈)

      [!NOTE] 耳机对频率的要求应该如何?

      flashcard

      三频均衡 1. 缺少低频/高频过多——对人体听力伤害大,人老了先损失的是高频辨识能力 2. 仅突出低频——不好听?

    2. 绝大多数使用场景中,入耳式损伤小耳塞式(平口耳塞)因为不隔音,需要提高音量来获取对音乐细节的辨识度。举个简单的例子,两个人在房间里谈话,50分贝就能听得很清楚。在大街上谈话70分贝两个人都经常听不清对方说的是什么。简单来说,你的耳蜗接受的声音越小,伤害越低。而入耳式耳机隔绝了外界噪音,你就不用开大声音来欣赏音乐。而且封闭式的腔体增加了耳机效果,所以你可以开的比平头小的多的声音来欣赏音乐。如果手头上有两种耳机的可以试试,入耳式我通常只开手机的两格音量,声音就够用了。现在各大耳机厂都在出入耳式耳机,平头出的越来越少,难道不能说明问题?平头旗舰你能数出几个来?

      [!NOTE] 大多数使用场景中,入耳式/耳罩式耳机,哪个对听力损伤小?

      flashcard

      入耳式,隔绝了外界噪音,你就不用开大声音来欣赏音乐

    1. If you would like to study how varying prompts causes changes in the evaluation score, check out the BigScience fork of this repo. We are currently working on upstreaming this capability to main.

      [!NOTE] LM-Eval 中,要为同个任务指定多个 prompt,可以使用?

      flashcard

      check out the BigScience fork of this repo

    2. For models loaded with the HuggingFace transformers library, any arguments provided via --model_args get passed to the relevant constructor directly. This means that anything you can do with AutoModel can be done with our library. For example, you can pass a local path via pretrained= or use models finetuned with PEFT by taking the call you would run to evaluate the base model and add ,peft=PATH to the model_args argument: python main.py \ --model hf-causal-experimental \ --model_args pretrained=EleutherAI/gpt-j-6b,peft=nomic-ai/gpt4all-j-lora \ --tasks openbookqa,arc_easy,winogrande,hellaswag,arc_challenge,piqa,boolq \ --device cuda:0 GPTQ quantized models can be loaded by specifying their file names in ,quantized=NAME (or ,quantized=True for default names) in the model_args argument: python main.py \ --model hf-causal-experimental \ --model_args pretrained=model-name-or-path,quantized=model.safetensors,gptq_use_triton=True \ --tasks hellaswag GGUF or GGML quantized models can be loaded by using llama-cpp-python server: python main.py \ --model gguf \ --model_args base_url=http://localhost:8000 \ --tasks hellaswag

      [!NOTE] LM-Eval 使用 🤗 Transformers 时,如何指定 AutoModel* 的参数?

      flashcard

      any arguments provided via --model_args get passed to the relevant constructor directly

    3. To help improve reproducibility, all tasks have a VERSION field. When run from the command line, this is reported in a column in the table, or in the "version" field in the evaluator return dict. The purpose of the version is so that if the task definition changes (i.e to fix a bug), then we can know exactly which metrics were computed using the old buggy implementation to avoid unfair comparisons. To enforce this, there are unit tests that make sure the behavior of all tests remains the same as when they were first implemented. Task versions start at 0, and each time a breaking change is made, the version is incremented by one. When reporting eval harness results, please also report the version of each task. This can be done either with a separate column in the table, or by reporting the task name with the version appended as such: taskname-v0.

      [!NOTE] 评测时,关于复现性,有什么好习惯?

      flashcard

      报告任务的版本

    1. Note that SymPy answer checking can be quite heavy on CPU resources and time-consuming for Maj@K at high K.

      [!NOTE] 使用 SymPy 进行答案检查时,需要注意什么?

      flashcard

      CPU 负担比较高

    1. 散序处理(Out of Order Execution)是现代CPU非常重要特性,x86、arm的新架构基本都支持这种特性,要进行指令优化必须要对散序处理有个基本的了解。 与散序处理相对应的就是顺序处理(In Order Execution),两者在指令的处理步骤上存在明显区别: 顺序处理 In Order Execution : 获取指令。 如果操作数已就位(操作数位于寄存器内),则可以把指令分配到相应的功能单元。如果有一个或多个操作数未就位,则需要花费数个时钟周期来获取该操作数,在这段时间内处理器会处于停止状态。 所有操作数就位后,指令会被相应的功能单元执行。 功能单元把执行结果写回寄存器。 散序处理 Out of Order Execution : 获取指令。 指令进入指令队列。 在操作数就位前,指令会在队列内进行等待。一旦操作数就位,指令就会处于就绪状态,处于就绪状态的指令可以先于前面的未就绪指令出队列。 指令在出队列后会被分配到相应的功能单元执行。 指令进入重排序队列。 重排序队列需要指令按照原本的顺序把执行结果写回到用户可见的寄存器/内存,写回后从队列中删除指令。   散序处理的第6步,也就是最后一个步骤,被称为Instruction retirement,具体实现的部分被称为Retirement unit。程序指令原来的执行顺序叫做program order,不过在散序处理的CPU中,指令的处理顺序是基于数据的,当指令在其所依赖的数据就绪后即可开始执行,这种执行顺序叫做data order。不过对于用户来说,为了便于调试与维护,还是有必要在用户可见的范围内维持程序原有的顺序,retirement unit做的就是这个工作。Retirement unit把指令的执行结果按照program order写回用户可见的寄存器,使得用户以为程序是顺序执行的,实际上在CPU内部,指令是散序执行的。   散序处理总体上可以按照上面的描述进行理解,细分开来则涉及到较多的CPU特性。

      [!NOTE] 乱序执行 (Out of Order Execution) 的基本思想是?

      flashcard

      指令的处理顺序是基于数据的,当指令在其所依赖的数据就绪后即可开始执行,这种执行顺序叫做data order。 不过对于用户来说,为了便于调试与维护,还是有必要在用户可见的范围内维持程序原有的顺序,retirement unit做的就是这个工作

    1. --appendAppend run

      [!NOTE] wandb sync 如何附加 run 的信息?

      flashcard

      --append

    1. 现在假设有两个操作系统os1、os2驻留集分别为m,n,且0<m<n。 为方便描述,需要引入两个个人定义的概念: 1.稳定区:即在os2的驻留集中,存在一个大小为m的区域,其页面次序与os1完全一致。也即os1是os2的真子集。 2.稳定状态:即os2中存在稳定区时候的状态。Belady发生的两个必要条件:1.os2不存在稳定区。2.接下来访问的页面在os1中有,而os2没有。 而FIFO算法会产生Belady现象的根本原因则是,在os2中,尽管驻留集更大,但并不是一直存在一个“稳定区”。这会导致一个结果:os1与os2换出的页面有可能不一致。如果os2换出的页面p2是下一步将要访问的,且os1中仍旧持有p2,此时os2就将比os1多置换一次,便产生了Belady现象。

      [!NOTE] Belady 反常的发生需要哪些条件?

      flashcard

      1.os2不存在稳定区。 2.接下来访问的页面在os1中有,而os2没有。

    1. belady现象的出现,是由于置换算法将需要经常访问的页面置换了出去导致的。例如FIFO算法,即便最开始进入内存的那个页面是最近以及未来要经常访问的,但是FIFO还是选择把它换出去。FIFO选择替换最早进入内存的页面,没有考虑到这个页面未来是否可能会经常访问,所以导致了belady现象。类似的算法还有clock算法,clock算法本质跟FIFO一样,假如物理页帧数为4,并页面p1、p2、p3、p4先后被访问并被载入物理页帧,从p4被载入内存的时刻t1开始,直到下一次发生缺页的时刻t2为止这段时间内最经常访问的页是p1,根据局部性原理,未来p1有很大可能要继续访问。但是clock算法给这四个页面都设置了访问位,而且很遗憾的是,这个访问位只有一个比特,它根本区分不了这个四个页面中谁被访问最频繁,这4个页面的访问位都是1,根据clock算法,t2时候发生缺页,clock算法按照被载入内存的时间先后扫描所有页帧,将第一个访问位为0的页面置换出去,但是显然这四个页面的访问位都是1,所以clock算法会将这4个页面的访问位依次置为0,然后循环扫描,将p1置换出去。所以clock算法是存在belady现象的。

      [!NOTE] 时钟置换算法存在 belady 现象吗?

      flashcard

      存在。 它只能够区分有没有被访问过,至于在那些都被访问过的页面中,谁是最频繁被访问的、谁是最近被访问的,clock算法区分不了。所以导致它经过一轮扫描以后退化成为FIFO。

    1. 超线程(Hyperthread, Simultaneous multithreading)处理器 将CPU内部暂时闲置处理资源充分调动起来 寄存器、程序计数器独立 算术计算单元等硬件共用 不适合计算密集型任务 适合IO密集型任务

      [!NOTE] 超线程处理器的基本思想与适用场景为?

      flashcard

      将CPU内部寄存器、程序计数器等暂时闲置处理资源充分调动起来 仅适合IO密集型任务

    1. 优先级反置(Priority Inversion) 高优先级进程长时间等待低优先级进程所占用资源的现象 基于优先级的可抢占调度算法存在优先级反置问题

      [!NOTE] 优先级反置问题可能在什么条件下出现?

      flashcard

      低优先级资源占据高优先级资源

    1. 进程的工作集示例

      [!NOTE] 进程的工作集如何决定其被分配的物理页面数?

      flashcard

      $[t-Δ,t]$ 区间内用到的页面数

    1. 页面置换算法的分类 局部页面置换算法 置换页面的选择范围仅限于当前进程占用的物理页面内 最优算法、先进先出算法、最近最久未使用算法 时钟算法、最不常用算法 全局页面置换算法 置换页面的选择范围是所有可换出的物理页面 工作集算法、缺页率算法

      [!NOTE] 局部/全局页面置换算法有什么区别?

      flashcard

      置换页面的选择范围 局部:仅限于当前进程占用的物理页面 全局:置换页面的选择范围是所有可换出的物理页面

    1. 虚拟存储的性能 有效存储访问时间(EAT, Effective memory Access Time) EAT = 内存访问时间 ∗*∗ (1-p) + 缺页异常处理时间 缺页异常处理时间 = 磁盘访问时间*p(1+q) p: 缺页率; q: 写回概率

      [!NOTE] 如何定量衡量 VM 的性能?

      flashcard

      有效存储访问时间(EAT, Effective memory Accesss Time) 内存访问+外存读取+写回

    1. Q:为何用jr t1 而不是 call trap_handler完成跳转? 在内存布局中,这条 .text.trampoline 段中的跳转指令和 trap_handler 都在代码段之内,汇编器(Assembler)和链接器(Linker)会根据 linker-qemu.ld 的地址布局描述,设定跳转指令的地址,并计算二者地址偏移量,让跳转指令的实际效果为当前 pc 自增这个偏移量。 这条跳转指令在被执行的时候,它的虚拟地址被操作系统内核设置在地址空间中的最高页面之内,所以加上这个偏移量并不能正确的得到 trap_handler 的入口地址。

      [!NOTE] 支持 VM 的 OS 中,Trap 为什么用 jr t1 而不是 call trap_handler 完成?

      flashcard

      call 指令被实现为相对 PC 偏移,偏移量则在静态链接过程中计算得到 但在虚拟内存中,这个偏移量可能已经不再适用?

    2. Q:为何不直接把Trap上下文仍放到应用的内核栈中呢? 访问内核栈中的Trap上下文地址,需要先切换页表; 页表信息放在 Trap上下文中,形成了相互依赖。

      [!NOTE] 带页表的 OS 中,为何不直接把Trap上下文仍放到应用的内核栈中呢?

      flashcard

      访问内核栈中的 Trap上下文地址,需要先切换页表; 页表信息放在 Trap上下文中,形成了相互依赖。

    1. 由小到大在空闲块中找最小可用块 如空闲块过大,对可用空闲块进行二等分,直到得到合适可用空闲块

      [!NOTE] 伙伴系统分配/搜索块,具体是如何实现的?

      flashcard

      由小到大在空闲块中找最小可用块(更容易适配)

    1. 伙伴系统分配器的主要优点是它的快速搜索和快速合并。主要缺点是要求块大小为 2 的幂可能导致显著的内部碎片。

      [!NOTE] 伙伴系统分配器的主要优点是?

      flashcard

      • 分配/搜索:基于二叉树搜索,非常快
      • 释放/合并:利用伙伴地址的性质,很容易检查伙伴块的情况并合并
    2. 关于伙伴系统的一个关键事实是,给定地址和块的大小,很容易计算出它的伙伴的地址。例如,一个块,大小为 32 字节,地址为:xxx⋯x00000xxx\cdots x00000xxx⋯x00000它的伙伴的地址为xxx⋯x10000xxx\cdots x10000xxx⋯x10000换句话说,一个块的地址和它的伙伴的地址只有一位不相同。

      [!NOTE] 伙伴系统在块地址上的关键性质是?

      flashcard

      一个块的地址和它的伙伴的地址只有一位不相同 给定地址和块的大小,很容易计算出它的伙伴快地址

    3. 伙伴系统(buddy system)是分离适配的一种特例,其中每个大小类都是 2 的籍。基本的思路是假设一个堆的大小为2m\small 2^m2m个字,我们为每个块大小2k\small2^k2k维护一个分离空闲链表,其中0⩽k⩽m\small 0\leqslant k \leqslant m0⩽k⩽m。请求块大小向上舍入到最接近的 2 的幂。最开始时,只有一个大小为 2m\small 2^m2m 个字的空闲块。为了分配一个大小为2k\small 2^k2k的块,我们找到第一个可用的、大小为2j\small 2^j2j的块,其中k⩽j⩽m\small k\leqslant j \leqslant mk⩽j⩽m。如果 j=k\small j=kj=k,那么我们就完成了。否则,我们递归地二分割这个块,直到当我们进行这样的分割时,每个剩下的半块(也叫做伙伴)被放置在相应的空闲链表中。要释放一个大小为2k\small 2^k2k的块,我们继续合并空闲的伙伴。当遇到一个已分配的伙伴时,我们就停止合并。

      [!NOTE] 伙伴系统(buddy system)的基本实现方法是?

      flashcard

      是分离适配的一种特例 为每个块大小 $2^k$ 维护一个分离空闲链表

    1. 逻辑地址(LA, Logical Address) :CPU执行机器指令时,用来指定一个操作数或者是一条指令的地址。也是用户编程时使用的地址。 线性地址(linear address)或也叫虚拟地址(virtual address) :跟逻辑地址类似,它也是一个不真实的地址。 逻辑地址指CPU在段式内存管理转换前的地址; 线性地址指CPU在页式内存管理转换前的地址。

      [!NOTE] 逻辑地址与线性地址有什么区别?

      flashcard

      逻辑地址指CPU在段式内存管理转换前的地址; 线性地址指CPU在页式内存管理转换前的地址。

    2. 逻辑地址与物理地址的关系 逻辑地址到物理地址的转换 逻辑地址 -> 线性地址(虚拟地址) -> 物理地址 在没有段式内存管理的情况下,逻辑地址与虚拟地址相同 在没有页式内存管理的情况下,逻辑地址、虚拟地址和物理地址都相同

      [!NOTE] 逻辑地址与线性地址有什么联系?

      flashcard

      逻辑地址 -> 线性地址(虚拟地址) -> 物理地址 在没有段式内存管理的情况下,逻辑地址与虚拟地址相同> 在没有页式内存管理的情况下,逻辑地址、虚拟地址和物理地址都相同

  3. Oct 2023
  4. huggingface.co huggingface.co
    1. torch_compile (bool, optional, defaults to False) — Whether or not to compile the model using PyTorch 2.0 torch.compile. This will use the best defaults for the torch.compile API. You can customize the defaults with the argument torch_compile_backend and torch_compile_mode but we don’t guarantee any of them will work as the support is progressively rolled in in PyTorch. This flag and the whole compile API is experimental and subject to change in future releases. torch_compile_backend (str, optional) — The backend to use in torch.compile. If set to any value, torch_compile will be set to True. Refer to the PyTorch doc for possible values and note that they may change across PyTorch versions. This flag is experimental and subject to change in future releases. torch_compile_mode (str, optional) — The mode to use in torch.compile. If set to any value, torch_compile will be set to True. Refer to the PyTorch doc for possible values and note that they may change across PyTorch versions. This flag is experimental and subject to change in future releases.

      [!NOTE] 🤗 Trainer 中如何开启 PyTorch 2 的编译功能?

      flashcard

      --torch_compile 系列选项

    2. skip_memory_metrics (bool, optional, defaults to True) — Whether to skip adding of memory profiler reports to metrics. This is skipped by default because it slows down the training and evaluation speed.

      [!NOTE] 🤗 Trainer 如何关闭跳过 memory metrics?

      flashcard

      --skip_memory_metrics False

    3. ray_scope (str, optional, defaults to "last") — The scope to use when doing hyperparameter search with Ray. By default, "last" will be used. Ray will then use the last checkpoint of all trials, compare those, and select the best one. However, other options are also available. See the Ray documentation for more options.

      [!NOTE] 🤗 Trainer 如何利用 Ray 进行超参数搜索?

      flashcard

      See the Ray documentation for more options.

    4. past_index (int, optional, defaults to -1) — Some models like TransformerXL or XLNet can make use of the past hidden states for their predictions. If this argument is set to a positive int, the Trainer will use the corresponding output (usually index 2) as the past state and feed it to the model at the next training step under the keyword argument mems.

      [!NOTE] 🤗 Trainer 模型推理中 past_index 有什么用?

      flashcard

      Some models like TransformerXL or XLNet can make use of the past hidden states for their predictions. the past state and feed it to the model at the next training step under the keyword argument mems.

    5. optim (str or training_args.OptimizerNames, optional, defaults to "adamw_torch") — The optimizer to use: adamw_hf, adamw_torch, adamw_torch_fused, adamw_apex_fused, adamw_anyprecision or adafactor.

      [!NOTE] 🤗 Trainer 有哪些 optimizer 可以选?

      flashcard

      adamw_hf, adamw_torch, adamw_torch_fused, adamw_apex_fused, adamw_anyprecision or adafactor

    6. logging_nan_inf_filter (bool, optional, defaults to True) — Whether to filter nan and inf losses for logging. If set to True the loss of every step that is nan or inf is filtered and the average loss of the current logging window is taken instead. logging_nan_inf_filter only influences the logging of loss values, it does not change the behavior the gradient is computed or applied to the model.

      [!NOTE] 🤗 Trainer 如何设置日志中是否忽略 nan/inf losses?

      flashcard

      logging_nan_inf_filter

    7. logging_first_step (bool, optional, defaults to False) — Whether to log and evaluate the first global_step or not.

      [!NOTE] 🤗 Trainer 如何设置 evalute 最初的模型?

      flashcard

      logging_first_step

    8. jit_mode_eval (bool, optional, defaults to False) — Whether or not to use PyTorch jit trace for inference.

      [!NOTE] 🤗 Trainer 如何使用 PyTorch JiT?

      flashcard

      --jit_mode_eval

    9. include_inputs_for_metrics (bool, optional, defaults to False) — Whether or not the inputs will be passed to the compute_metrics function. This is intended for metrics that need inputs, predictions and references for scoring calculation in Metric class.

      [!NOTE] 🤗 Trainer 如何将 inputs 也传入 Metric 对象?

      flashcard

      include_inputs_for_metrics

    10. group_by_length (bool, optional, defaults to False) — Whether or not to group together samples of roughly the same length in the training dataset (to minimize padding applied and be more efficient). Only useful if applying dynamic padding.

      [!NOTE] 🤗 Trainer 如何将 sample 按长度大致分组?

      flashcard

      --group_by_length

    11. full_determinism (bool, optional, defaults to False) — If True, enable_full_determinism() is called instead of set_seed() to ensure reproducible results in distributed training. Important: this will negatively impact the performance, so only use it for debugging.

      [!NOTE] 🤗 Trainer 如何实现完全可复现性?

      flashcard

      --full_determinism

    12. bf16_full_eval (bool, optional, defaults to False) — Whether to use full bfloat16 evaluation instead of 32-bit. This will be faster and save memory but can harm metric values. This is an experimental API and it may change.

      [!NOTE] 🤗 Trainer 默认使用什么数据格式执行 evaluation?

      flashcard

      fp32

    13. run_name (str, optional) — A descriptor for the run. Typically used for wandb and mlflow logging.

      [!NOTE] 🤗 Trainer 要设置所跟踪的运行的名称,可以使用?

      flashcard

      run_name=... 参数

    1. 物理页号和全部的标志位以某种固定的格式保存在一个结构体中,它被称为 页表项 (PTE, Page Table Entry) ,是利用虚拟页号在页表中查到的结果。 上图为 SV39 分页模式下的页表项,其中 [53:10] 这 44 位是物理页号,最低的 8 位 [7:0] 则是标志位,它们的含义如下(请注意,为方便说明,下文我们用 页表项的对应虚拟页面 来表示索引到 一个页表项的虚拟页号对应的虚拟页面): 仅当 V(Valid) 位为 1 时,页表项才是合法的; R/W/X 分别控制索引到这个页表项的对应虚拟页面是否允许读/写/取指; U 控制索引到这个页表项的对应虚拟页面是否在 CPU 处于 U 特权级的情况下是否被允许访问; G 我们暂且不理会; A(Accessed) 记录自从页表项上的这一位被清零之后,页表项的对应虚拟页面是否被访问过; D(Dirty) 则记录自从页表项上的这一位被清零之后,页表项的对应虚拟页表是否被修改过。 由于pte只有54位,每一个页表项我们用一个8字节的无符号整型来记录就已经足够。

      [!NOTE] (Sv39 中)页表项的组成为?

      flashcard

      10 位保留+44位物理页号+10位标志位

    1. MMU 应该如何知道当前做地址转换的时候要查哪一个页表呢?回到 satp CSR 的布局 , 其中的 PPN 字段指的就是多级页表根节点所在的物理页号。因此,每个应用的地址空间就可以用包含了它多级页表根节点所在物理页号 的 satp CSR 代表。在我们切换任务的时候, satp 也必须被同时切换。

      [!NOTE] (RISC-V中)多级页表根节点所在的物理页号如何获取?

      flashcard

      satp CSR 的 PPN 字段 每个应用的地址空间就可以用包含了它多级页表根节点所在物理页号 的 satp CSR 代表

    2. SV39 多级页表相比线性表到底能节省多少内存呢?这里直接给出结论:设某个应用地址空间实际用到的区域总大小为 S 字节,则地址空间对应的多级页表消耗内存为 S512 左右。下面给出了详细分析,对此 不感兴趣的读者可以直接跳过。

      [!NOTE] 多级页表相比线性页表能节省多少内存?

      flashcard

      仅消耗 1/512?

    3. 非叶节点的页表项标志位含义和叶节点相比有一些不同: 当 V 为 0 的时候,代表当前指针是一个空指针,无法走向下一级节点,即该页表项对应的虚拟地址范围是无效的; 只有当V 为1 且 R/W/X 均为 0 时,表示是一个合法的页目录表项,其包含的指针会指向下一级的页表。 注意: 当V 为1 且 R/W/X 不全为 0 时,表示是一个合法的页表项,其包含了虚地址对应的物理页号。 在这里我们给出 SV39 中的 R/W/X 组合的含义:

      [!NOTE] (RISC-V的)多级页表中,非叶节点的页表项标志位含义具体是?

      flashcard

      只有当V 为1 且 R/W/X 均为 0 时,表示是一个合法的页目录表项,其包含的指针会指向下一级的页表

    4. 默认情况下 MMU 未被使能,此时无论 CPU 位于哪个特权级,访存的地址都会作为一个物理地址交给对应的内存控制单元来直接 访问物理内存。我们可以通过修改 S 特权级的一个名为 satp 的 CSR 来启用分页模式,在这之后 S 和 U 特权级的访存 地址会被视为一个虚拟地址,它需要经过 MMU 的地址转换变为一个物理地址,再通过它来访问物理内存;而 M 特权级的访存地址,我们可设定是内存的物理地址。 注解 M 特权级的访存地址被视为一个物理地址还是一个需要经历和 S/U 特权级相同的地址转换的虚拟地址取决于硬件配置,在这里我们不会进一步探讨。

      [!NOTE] RISC-V 中,如何开启虚拟内存机制?

      flashcard

      修改 S 特权级的一个名为 satp 的 CSR 来启用分页模式

    1. 可以想象对于不同的应用来说,该映射可能是不同的, 即 MMU 可能会将来自不同两个应用地址空间的相同虚拟地址翻译成不同的物理地址。要做到这一点,就需要硬件提供一些寄存器 ,软件可以对它进行设置来控制 MMU 按照哪个应用的地址空间进行地址转换。于是,将应用的数据放到物理内存并进行管理,而 在任务切换的时候需要将控制 MMU 选用哪个应用的地址空间进行映射的那些寄存器也一并进行切换,则是作为软件部分的内核需 要完成的工作。

      [!NOTE] 操作系统在虚拟内存中发挥了什么作用?

      flashcard

      在任务切换的时候需要将控制 MMU 选用哪个应用的地址空间进行映射的那些寄存器也一并进行切换

    1. call rd, symbol x[rd] = pc+8; pc = &symbol调用 (Call). 伪指令(Pesudoinstruction), RV32I and RV64I.把下一条指令的地址(pc+8)写入 x[rd],然后把 pc 设为 symbol。等同于 auipc rd, offestHi,再加上一条 jalr rd, offsetLo(rd). 若省略了 rd,默认为 x1.

      [!NOTE] RISC-V 中,call 指令有哪些操作数?有什么效果?需要注意什么?

      flashcard

      call rd, symbolrd 默认为 ra x[rd] = pc+8; pc = &symbol 注意:下一条指令地址为 pc+8,因为实际等效于 2 条指令

    2. lui rd, immediate x[rd] = sext(immediate[31:12] << 12)高位立即数加载 (Load Upper Immediate). U-type, RV32I and RV64I.将符号位扩展的 20 位立即数 immediate 左移 12 位,并将低 12 位置零,写入 x[rd]中。

      [!NOTE] RISC-V 中 lui 会如何处理低 12 位?

      flashcard

      覆盖为 0

    3. sret ExceptionReturn(Supervisor)管理员模式例外返回(Supervisor-mode Exception Return). R-type, RV32I and RV64I 特权指令。从管理员模式的例外处理程序中返回,设置 pc 为 CSRs[spec],权限模式为 CSRs[sstatus].SPP,CSRs[sstatus].SIE 为 CSRs[sstatus].SPIE,CSRs[sstatus].SPIE 为 1,CSRs[sstatus].spp 为 0。

      [!NOTE] RISC-V 中 sret 的功能为?

      flashcard

      1. 设置 pc 为 CSRs[spec]
      2. 权限模式为 CSRs[sstatus].SPP,
      3. CSRs[sstatus].SIE 为 CSRs[sstatus].SPIE,
      4. CSRs[sstatus].SPIE 为 1,
      5. CSRs[sstatus].spp 为 0
    4. csrrw rd, csr, zimm[4:0] t = CSRs[csr]; CSRs[csr] = x[rs1]; x[rd] = t读后写控制状态寄存器 (Control and Status Register Read and Write). I-type, RV32I and RV64I.记控制状态寄存器 csr 中的值为 t。把寄存器 x[rs1]的值写入 csr,再把 t 写入 x[rd]。

      [!NOTE] RISC-V 中 csrrw 的功能为?

      flashcard

      读后写控制状态寄存器 (Control and Status Register Read and Write). I-type, RV32I and RV64I. 记控制状态寄存器 csr 中的值为 t 。把寄存器 x[rs1]的值写入 csr,再把 t 写入 x[rd]。

    5. csrw csr, rs1 CSRs[csr] = x[rs1]写控制状态寄存器 (Control and Status Register Set). 伪指令(Pesudoinstruction), RV32I andRV64I.对于 x[rs1]中每一个为 1 的位,把控制状态寄存器 csr 的的对应位置位,等同于 csrrs x0, csr,rs1.

      [!NOTE] RISC-V 中 csrw 的功能为?

      flashcard

      对于 x[rs1]中每一个为 1 的位,把控制状态寄存器 csr 的的对应位置位

    6. csrrs rd, csr, rs1 t = CSRs[csr]; CSRs[csr] = t | x[rs1]; x[rd] = t读后置位控制状态寄存器 (Control and Status Register Read and Set). I-type, RV32I and RV64I.记控制状态寄存器 csr 中的值为 t。把 t 和寄存器 x[rs1]按位或的结果写入 csr,再把 t 写入x[rd]。

      [!NOTE] RISC-V 中 csrrs 的功能 为?

      flashcard

      记控制状态寄存器 csr 中的值为 t 。把 t 和寄存器 x[rs1]按位或的结果写入 csr,再把 t 写入 x[rd]

    7. 第十章 RV32/64 特权架构

      [!NOTE] 要了解 RISC-V 特权级架构(CSR 寄存器),有什么好用的材料?

      flashcard

      • RISC-V 手册 Chap10
    1. The reason is that t5x wrapps arround sentencepiece, and adds the extra id to the vocab, but they are not saved that way. We don't add them to the vocab, so when we tokenize, we split on special tokens, thus the sentencepiece model only sees: >>> tokenizer.sp_model.encode(". Hello") [273, 274, 9] While the original model never sees a . (or a lot of other characters) alone, and thus we add an extra space... This is a bug fix with regards to training, it is breaking in the sense that is should remove the space.

      [!NOTE] T5/LLaMA 类的 tokenizer 曾经出现过什么问题?

      flashcard

      添加特殊 token 存在错误?

    1. model = AutoModel.from_pretrained("private/model", token=access_token)

      [!NOTE] 🤗 from_pretrained() 中如何使用 token?

      flashcard

      参数 token=access_token

    1. Create a new dataset with rows selected following the list/array of indices. Example: Copied >>> from datasets import load_dataset >>> ds = load_dataset("rotten_tomatoes", split="validation") >>> ds.select(range(4))

      [!NOTE] 🤗 Datasets 如何获取数据集的一部分?

      flashcard

      ds.select(range(n))

    1. The reentrant variant of checkpoint (use_reentrant=True) and the non-reentrant variant of checkpoint (use_reentrant=False) differ in the following ways: Non-reentrant checkpoint stops recomputation as soon as all needed intermediate activations have been recomputed. This feature is enabled by default, but can be disabled with set_checkpoint_early_stop(). Reentrant checkpoint always recomputes function in its entirety during the backward pass. The reentrant variant does not record the autograd graph during the forward pass, as it runs with the forward pass under torch.no_grad(). The non-reentrant version does record the autograd graph, allowing one to perform backward on the graph within checkpointed regions. The reentrant checkpoint only supports the torch.autograd.backward() API for the backward pass without its inputs argument, while the non-reentrant version supports all ways of performing the backward pass. At least one input and output must have requires_grad=True for the reentrant variant. If this condition is unmet, the checkpointed part of the model will not have gradients. The non-reentrant version does not have this requirement. The reentrant version does not consider tensors in nested structures (e.g., custom objects, lists, dicts, etc) as participating in autograd, while the non-reentrant version does. The reentrant checkpoint does not support checkpointed regions with detached tensors from the computational graph, whereas the non-reentrant version does. For the reentrant variant, if the checkpointed segment contains tensors detached using detach() or with torch.no_grad(), the backward pass will raise an error. This is because checkpoint makes all the outputs require gradients and this causes issues when a tensor is defined to have no gradient in the model. To avoid this, detach the tensors outside of the checkpoint function.

      [!NOTE] PyTorch 激活检查点中,use_reentrant 对应的两个实现有什么区别?

      flashcard

      • 停止时机
      • 是否记录自动微分图
      • 是否允许 torch.autograd.backward() 带参数
      • ...
    2. There are currently two checkpointing implementations available, determined by the use_reentrant parameter. It is recommended that you use use_reentrant=False. Please refer the note below for a discussion of their differences.

      [!NOTE] PyTorch 中,使用激活检查点时,需要注意什么?

      flashcard

      有两个实现,取决于 use_reentrant 的取值

    1. accelerate launch --multi_gpu --mixed_precision=fp16 --num_processes=2 {script_name.py} {--arg1} {--arg2} ...

      [!NOTE] accelerate launch 传递参数有什么要注意的?

      flashcard

      --<option>=<val> 等于号?

    1. Values: NO — Do not use torch dynamo. EAGER — Uses PyTorch to run the extracted GraphModule. This is quite useful in debugging TorchDynamo issues. AOT_EAGER — Uses AotAutograd with no compiler, i.e, just using PyTorch eager for the AotAutograd’s extracted forward and backward graphs. This is useful for debugging, and unlikely to give speedups. INDUCTOR — Uses TorchInductor backend with AotAutograd and cudagraphs by leveraging codegened Triton kernels. Read more NVFUSER — nvFuser with TorchScript. Read more AOT_NVFUSER — nvFuser with AotAutograd. Read more AOT_CUDAGRAPHS — cudagraphs with AotAutograd. Read more OFI — Uses Torchscript optimize_for_inference. Inference only. Read more FX2TRT — Uses Nvidia TensorRT for inference optimizations. Inference only. Read more ONNXRT — Uses ONNXRT for inference on CPU/GPU. Inference only. Read more IPEX — Uses IPEX for inference on CPU. Inference only. Read more.

      [!NOTE] 🤗 Accelerate 支持哪些 DynamoBackend?

      flashcard

      见下

    1. Training Paradigm Arguments: The following arguments are useful for selecting which training paradigm to use. --use_deepspeed (bool) — Whether or not to use DeepSpeed for training. --use_fsdp (bool) — Whether or not to use FullyShardedDataParallel for training. --use_megatron_lm (bool) — Whether or not to use Megatron-LM for training. --use_xpu (bool) — Whether to use IPEX plugin to speed up training on XPU specifically.

      [!NOTE] 使用 accelerate launch 的布尔参数时,需要注意什么?

      flashcard

      不能用 "True" 等字符串赋值?

    2. accelerate estimate-memory {MODEL_NAME} --library_name {LIBRARY_NAME} --dtypes {dtype_1} {dtype_2} ...

      [!NOTE] 🤗 Accelerate 提供了什么估计模型内存占用的工具?

      flashcard

      accelerate estimate-memory

    3. -m, --module (bool) — Change each process to interpret the launch script as a Python module, executing with the same behavior as ‘python -m’. --no_python (bool) — Skip prepending the training script with ‘python’ - just execute it directly. Useful when the script is not a Python script.

      [!NOTE] 🤗 Accelerate launch 支持哪些特殊的文件类型?

      flashcard

      • Python 模组
      • 可执行文件
    1. Only when gradient_accumulation_steps is auto, the value passed while creating Accelerator object via Accelerator(gradient_accumulation_steps=k) will be used. When using DeepSpeed Plugin, the value from it will be used and it will overwrite the value passed while creating Accelerator object.

      [!NOTE] 🤗 Accelerate DeepSpeed 中,gradient_accumulation_steps 的哪个配置方法优先级更高?Accelerator(gradient_accumulation_steps=k) 还是 DeepSpeed Plugin?

      flashcard

      DeepSpeed Plugin

    1. register_buffer(name, tensor, persistent=True)[source] Adds a buffer to the module. This is typically used to register a buffer that should not to be considered a model parameter. For example, BatchNorm’s running_mean is not a parameter, but is part of the module’s state. Buffers, by default, are persistent and will be saved alongside parameters. This behavior can be changed by setting persistent to False. The only difference between a persistent buffer and a non-persistent buffer is that the latter will not be a part of this module’s state_dict. Buffers can be accessed as attributes using given names.

      [!NOTE] PyTorch 中,module.register_buffer 有什么用?

      flashcard

      保存模型参数之外的状态

    1. nn.ModuleList 并没有定义一个网络,它只是将不同的模块储存在一起。ModuleList中元素的先后顺序并不代表其在网络中的真实位置顺序,需要经过forward函数指定各个层的先后顺序后才算完成了模型的定义。

      [!NOTE] nn.ModuleListnn.Sequential 有什么区别?

      flashcard

    2. Sequential适用于快速验证结果,因为已经明确了要用哪些层,直接写一下就好了,不需要同时写__init__和forward; ModuleList和ModuleDict在某个完全相同的层需要重复出现多次时,非常方便实现,可以”一行顶多行“; 当我们需要之前层的信息的时候,比如 ResNets 中的残差计算,当前层的结果需要和之前层中的结果进行融合,一般使用 ModuleList/ModuleDict 比较方便。

      [!NOTE] PyTorch 中有哪些模型定义方法?如何选择?

      flashcard

      • 快速验证:nn.Sequential
      • 重复利用+管理之前层信息:nn.ModuleListnn.ModuleDict
    1. [1] git lfs clone 通过合并获取 LFS 对象的请求,减少了 LFS API 的调用,并行化 LFS 对象的下载,从而达到显著的速度提升。git lfs clone 命令同样也兼容没有使用 LFS 的仓库。即无论要克隆的仓库是否使用 LFS,都可以使用 git lfs clone 命令来进行克隆。 [2] 目前最新版本的 git clone 已经能够提供与 git lfs clone 一致的性能,因此自 Git LFS 2.3.0 版本起,git lfs clone 已不再推荐使用。

      [!NOTE] 有无必要使用 git lfs clone

      flashcard

      最新版本没有

    1. 图 9-12 展示了 MMU 如何利用页表来实现这种映射。CPU 中的一个控制寄存器,页表基址寄存器(Page Table Base Register,PTBR)指向当前页表。n 位的虚拟地址包含两个部分:一个 p 位的虚拟页面偏移(Virtual Page Offset,VPO)和一个(n−p)\small (n-p)(n−p)位的虚拟页号(Virtual Page Number,VPN)。MMU 利用 VPN 来选择适当的 PTE。例如,VPN 0 选择 PTE 0,VPN 1 选择 PTE 1,以此类推。将页表条目中物理页号(Physical Page Number,PPN)和虚拟地址中的 VP。串联起来,就得到相应的物理地址。注意,因为物理和虚拟页面都是 P 字节的,所以物理页面偏移(Physical Page Offset,PPO)和 VPO 是相同的。

      [!NOTE] MMU 是如何根据虚拟地址查找页表的?

      flashcard

      利用 VPN 来选择适当的 PTE。例如,VPN 0 选择 PTE 0,VPN 1 选择 PTE 1

    2. 给定了这种初始化设定,让我们来看看当 CPU 执行一条读地址 0x03d4 处字节的加载指令时会发生什么。(回想一下我们假定 CPU 读取 1 字节的字,而不是 4 字节的字。)为了开始这种手工的模拟,我们发现写下虚拟地址的各个位,标识出我们会需要的各种字段,并确定它们的十六进制值,是非常有帮助的。当硬件解码地址时,它也执行相似的任务。

      [!NOTE] 手工计算地址翻译时,有什么技巧?

      flashcard

      1. 写下虚拟地址的各个位,
      2. 标识出我们会需要的各种字段,并确定它们的十六进制
    3. 因为 TLB 有 4 个组,所以 VPN 的低 2 位就作为组索引(TLBI)。VPN 中剩下的高 6 位作为标记(TLBT),用来区别可能映射到同一个 TLB 组的不同的 VPN。

      [!NOTE] 缓存的(组)相联度是什么?

      flashcard

      基址(注意不包括偏移) 总共长 a 位,缓存的(组)相联度为 2^b,则该缓存为 2^{a-b} 路组相连的 地址通常如下分割: - 低 (a-b) 位作为索引,实现相邻块的区分 - 高 b 位作为标记,实现地址的最终确认

    4. 对于只有一级的页表结构,PPO 和 VPO 是相同的。

      [!QUESTION] 对于只有一级的页表结构,PPO 和 VPO 是相同的。对于多级页表结构,两者不同吗?

      flashcard

      CSAPP 什么意思?

    5. 图 9-18 描述了使用 k 级页表层次结构的地址翻译。虚拟地址被划分成为 k 个 VPN 和 1 个 VPO。每个 VPN i 都是一个到第 i 级页表的索引,其中 1⩽i⩽k\small 1\leqslant i \leqslant k1⩽i⩽k 。第 j 级页表中的每个 PTE,1⩽j⩽k−1\small 1 \leqslant j \leqslant k-11⩽j⩽k−1,都指向第 j+1 级的某个页表的基址。第 k 级页表中的每个 PTE 包含某个物理页面的 PPN,或者一个磁盘块的地址。为了构造物理地址,在能够确定 PPN 之前,MMU 必须访问为个 PTE。对于只有一级的页表结构,PPO 和 VPO 是相同的。

      [!NOTE] k 级页表的虚拟地址是如何经过地址翻译的?

      flashcard

      虚拟地址被划分成为 k 个 VPN 和 1 个 VPO。每个 VPN i 都是一个到第 i 级页表的索引,其中 1<=i<=k

    6. TLB 是一个小的、虚拟寻址的缓存,其中每一行都保存着一个由单个 PTE 组成的块。TLB 通常有高度的相联度。如图 9-15 所示,用于组选择和行匹配的索引和标记字段是从虚拟地址中的虚拟页号中提取出来的。如果 TLB 有T=2t\small T = 2^tT=2t个组,那么 TLB 索引(TLBI)是由 VPN 的 t 个最低位组成的,而 TLB 标记(TLBT)是由 VPN 中剩余的位组成的。

      [!NOTE] TLB 的行的内容为?

      flashcard

      • 数值上,就是一个 PTE
      • 解释上,VPN 被分割为高位的 TLB 标记与低位的 TLB 索引
    7. 在任何既使用虚拟内存又使用 SRAM 高速缓存的系统中,都有应该使用虚拟地址还是使用物理地址来访问 SRAM 高速缓存的问题。尽管关于这个折中的详细讨论已经超出了我们的讨论范围,但是大多数系统是选择物理寻址的。使用物理寻址,多个进程同时在高速缓存中有存储块和共享来自相同虚拟页面的块成为很简单的事情。而且,高速缓存无需处理保护问题,因为访问权限的检査是地址翻译过程的一部分。图 9-14 展示了一个物理寻址的高速缓存如何和虚拟内存结合起来。主要的思路是地址翻译发生在高速缓存查找之前。注意,页表条目可以缓存,就像其他的数据字一样。

      [!NOTE] SRAM Cache 一般使用虚拟/物理寻址?为什么?

      flashcard

      物理寻址,便于 - 内存共享 - 由地址翻译检查访问权限

    1. 为了我们的目的,我们将假设每个 PTE 是由一个有效位(valid bit)和一个 n 位地址字段组成的。有效位表明了该虚拟页当前是否被缓存在 DRAM 中。如果设置了有效位,那么地址字段就表示 DRAM 中相应的物理页的起始位置,这个物理页中缓存了该虚拟页。如果没有设置有效位,那么一个空地址表示这个虚拟页还未被分配。否则,这个地址就指向该虚拟页在磁盘上的起始位置。图 9-4 中的示例展示了一个有 8 个虚拟页和 4 个物理页的系统的页表。四个虚拟页(VP 1、VP 2、VP 4 和 VP 7)当前被缓存在 DRAM 中。两个页(VP 0 和 VP 5 )还未被分配,而剩下的页(VP 3 和 VP 6)已经被分配了,但是当前还未被缓存。图 9-4 中有一个要点要注意,因为 DRAM 缓存是全相联的,所以任意物理页都可以包含任意虚拟页。

      [!NOTE] PTE 的内容(注意不是索引)组成为?

      flashcard

      一个有效位(valid bit)和一个 n 位地址字段

    1. 对于 V2Ray,它的验证方式包含时间,就算是配置没有任何问题,如果时间不正确,也无法连接 V2Ray 服务器的,服务器会认为你这是不合法的请求。所以系统时间一定要正确,只要保证时间误差在90秒之内就没问题。

      [!NOTE] V2Ray 对时间有什么要求?

      flashcard

      保证时间误差在90秒之内

    1. Git LFS一般仅仅下载本地切换需要的提交的文件。但是,你可以使用git lfs fetch –recent强制Git LFS下载附加的内容,因为其他人最近修改了分支。 $ git lfs fetch --recent

      [!NOTE] git lfs 默认会下载哪些提交?

      flashcard

      一般仅仅下载本地切换需要的提交的文件 可以使用 git lfs fetch –recent 强制Git LFS下载附加的内容

    2. git lfs pull为当前的提交下载所有丢失的Git LFS内容: $ git lfs pull Git LFS: (4 of 4 files) 1.14 MB / 1.15 MB

      [!NOTE] git lfs pull 的功能为?

      flashcard

      为当前的提交下载所有丢失的Git LFS内容

    3. 如果你正在克隆包含大量LFS文件的仓库,明确表明你在使用Git LFS命令可以提高响应能力: $ git lfs clone git@bitbucket.org:tpettersen/Atlasteroids.gitCloning into 'Atlasteroids'... remote: Counting objects: 156, done. remote: Compressing objects: 100% (154/154), done. remote: Total 156 (delta 87), reused 0 (delta 0) Receiving objects: 100% (156/156), 54.04 KiB | 0 bytes/s, done. Resolving deltas: 100% (87/87), done. Checking connectivity... done.** Git LFS**: (4 of 4 files) 1.14 MB / 1.15 MB 相比Git LFS逐个下载,git lfs clone等待切换完成,然后把必需的Git LFS文件打包下载,这利用并行下载的优势,明显减少了HTTP请求的数量和进程的陡增(这尤其在Windows中作用明显)。

      [!NOTE] 如何加快克隆包含大量大文件的仓库?

      flashcard

      git lfs clone git lfs clone等待切换完成,然后把必需的Git LFS文件打包下载,这利用并行下载的优势,明显减少了HTTP请求的数量和进程的陡增(这尤其在Windows中作用明显)

    1. 如果你的仓库包含大量文件或大文件(比如二进制文件或视频文件),执行 git add . 可能会非常耗时。这是因为Git需要计算每个文件的哈希值并将其添加到索引中。当文件太大时,计算哈希值和写入索引将会消耗大量时间。

      [!NOTE] 为什么 git add 大文件会很慢?

      flashcard

      因为Git需要计算每个文件的哈希值并将其添加到索引中。当文件太大时,计算哈希值和写入索引将会消耗大量时间

    1. 段式存储在内存保护方面有优势,页式存储在内存利用和优化转移到后备存储方面有优势。

      [!NOTE] 为什么说段式存储在内存保护方面有优势?

      flashcard

      段级别的权限管理与实际要求对应更密切 与段式存储相比,分页式存储在防止缓冲区溢出等安全漏洞方面可能不如段式存储那么强大,因为在分页式存储中,如果一个页面被分配了可写权限,那么在该页面上的所有数据都可以被写入,这增加了攻击者滥用内存的机会。

    2. 反置页表 基于Hash映射值查找对应页表项中的物理页号 任务/进程id与页号的Hash值可能有冲突 页表项中包括保护位、修改位、访问位和存在位等标识

      [!NOTE] 反置页表的基本思想是?

      flashcard

      基于Hash映射值查找对应页表项中的物理页号

    1. 在何处保存未被映射的页? 交换空间(磁盘/文件形态) 采用特殊格式存储未被映射的页面 磁盘上的文件(代码或数据)

      [!NOTE] 交换空间与一般的磁盘/文件有什么区别?

      flashcard

      特殊格式?

    2. 局部性原理 局部性(locality):程序在执行过程中的一个较短时期,所执行的指令地址和指令的操作数地址,分别局限于一定区域 时间局部性:一条指令的一次执行和下次执行,一个数据的一次访问和下次访问都集中在一个较短时期内 空间局部性:当前指令和邻近时间的几条指令,当前访问的数据和邻近时间访问的几个数据都集中在一个较小区域内 分支局部性:一条跳转指令的两次执行,很可能跳到相同的内存位置 局部性的意义:如果大部分程序运行具有局部性特征,则虚拟存储技术是能够实现的,而且可取得满意的效果

      [!NOTE] 虚拟内存机制有效的基本假设是?

      flashcard

      局部性

    1. check if tor is running on port 9050: systemctl status tor

      [!NOTE] Shell 中如何检查 tor 工作情况?

      flashcard

      ``systemctl status tor

    1. 10ms(也就是一个tick)

      [!NOTE] 计算机系统结构中,一个 tick 是指?

      flashcard

      10ms

    2. 另外一个 64 位的 CSR mtimecmp 的作用是:一旦计数器 mtime 的值超过了 mtimecmp,就会触发一次时钟中断。这使得我们可以方便的通过设置 mtimecmp 的值来决定下一次时钟中断何时触发。

      [!NOTE] RISC-V 如何控制下一次时钟中断何时触发?

      flashcard

      64 位的 CSR mtimecmp 的作用是:一旦计数器 mtime 的值超过了 mtimecmp,就会触发一次时钟中断

    3. 由于需要一种计时机制,RISC-V 架构要求处理器要有一个内置时钟,其频率一般低于 CPU 主频。此外,还有一个计数器统计处理器自上电以来经过了多少个内置时钟的时钟周期。在 RV64 架构上,该计数器保存在一个 64 位的 CSR mtime 中,我们无需担心它的溢出问题,在内核运行全程可以认为它是一直递增的。

      [!NOTE] RISC-V 如何记录内置时钟周期?

      flashcard

      64 位的 CSR mtime

    4. RISC-V 架构的 U 特权级中断 目前,RISC-V 用户态中断作为代号 N 的一个指令集拓展而存在。有兴趣的读者可以阅读最新版的 RISC-V 特权级架构规范一探究竟。

      [!NOTE] RISC-V 如何实现用户态中断?

      flashcard

      代号 N 的一个指令集拓展

    5. 默认情况下,当 Trap 进入某个特权级之后,在 Trap 处理的过程中同特权级的中断都会被屏蔽。这里我们还需要对第二章介绍的 Trap 发生时的硬件机制做一下补充,同样以 Trap 到 S 特权级为例: 当 Trap 发生时,sstatus.sie 会被保存在 sstatus.spie 字段中,同时 sstatus.sie 置零,这也就在 Trap 处理的过程中屏蔽了所有 S 特权级的中断; 当 Trap 处理完毕 sret 的时候, sstatus.sie 会恢复到 sstatus.spie 内的值。 也就是说,如果不去手动设置 sstatus CSR ,在只考虑 S 特权级中断的情况下,是不会出现 嵌套中断 (Nested Interrupt) 的。嵌套中断是指在处理一个中断的过程中再一次触发了中断从而通过 Trap 来处理。由于默认情况下一旦进入 Trap 硬件就自动禁用所有同特权级中断,自然也就不会再次触发中断导致嵌套中断了。

      [!NOTE] 默认情况下,是否可能发生嵌套中断?

      flashcard

      不可能 当 Trap 发生时,sstatus.sie 会被保存在 sstatus.spie 字段中,同时 sstatus.sie 置零,这也就在 Trap 处理的过程中屏蔽了所有 S 特权级的中断

    6. 如果中断没有被屏蔽,那么接下来就需要 Trap 进行处理,而具体 Trap 到哪个特权级与一些中断代理 CSR 的设置有关。默认情况下,所有的中断都需要 Trap 到 M 特权级处理。而设置这些代理 CSR 之后,就可以 Trap 到低特权级处理,但是 Trap 到的特权级不能低于中断的特权级。事实上所有的异常默认也都是 Trap 到 M 特权级处理的,它们也有一套对应的异常代理 CSR ,设置之后也可以 Trap 到低优先级来处理异常。 我们会在 附录 C:深入机器模式:RustSBI 中再深入介绍中断/异常代理。

      [!NOTE] 中断具体 Trap 到哪个特权级处理由什么决定?

      flashcard

      与一些中断代理 CSR 的设置有关。 - 默认情况下,所有的中断都需要 Trap 到 M 特权级处理。 - 而设置这些代理 CSR 之后,就可以 Trap 到低特权级处理, - 但是 Trap 到的特权级不能低于中断的特权级。

    7. 以内核所在的 S 特权级为例,中断屏蔽相应的 CSR 有 sstatus 和 sie 。sstatus 的 sie 为 S 特权级的中断使能,能够同时控制三种中断,如果将其清零则会将它们全部屏蔽。即使 sstatus.sie 置 1 ,还要看 sie 这个 CSR,它的三个字段 ssie/stie/seie 分别控制 S 特权级的软件中断、时钟中断和外部中断的中断使能。比如对于 S 态时钟中断来说,如果 CPU 不高于 S 特权级,需要 sstatus.sie 和 sie.stie 均为 1 该中断才不会被屏蔽;如果 CPU 当前特权级高于 S 特权级,则该中断一定会被屏蔽。

      [!NOTE] 中断屏蔽涉及到哪些 CSR?

      flashcard

      sstatussie

    8. 在判断中断是否会被屏蔽的时候,有以下规则: 如果中断的特权级低于 CPU 当前的特权级,则该中断会被屏蔽,不会被处理; 如果中断的特权级高于与 CPU 当前的特权级或相同,则需要通过相应的 CSR 判断该中断是否会被屏蔽。

      [!NOTE] 判断中断是否会被屏蔽的时候,有什么规则?

      flashcard

      1. 如果中断的特权级低于 CPU 当前的特权级,则该中断会被屏蔽,不会被处理;
      2. 如果中断的特权级高于与 CPU 当前的特权级或相同,则需要通过相应的 CSR 判断该中断是否会被屏蔽。
    9. 相比异常,中断和特权级之间的联系更为紧密,可以看到这三种中断每一个都有 M/S 特权级两个版本。中断的特权级可以决定该中断是否会被屏蔽,以及需要 Trap 到 CPU 的哪个特权级进行处理。

      [!NOTE] 中断的特权级会造成哪些影响?

      flashcard

      可以决定该中断是否会被屏蔽,以及需要 Trap 到 CPU 的哪个特权级进行处理

    10. 从底层硬件的角度区分同步和异步 从底层硬件的角度可能更容易理解这里所提到的同步和异步。以一个处理器传统的五级流水线设计而言,里面含有取指、译码、算术、 访存、寄存器等单元,都属于执行指令所需的硬件资源。那么假如某条指令的执行出现了问题,一定能被其中某个单元看到并反馈给流水线控制单元,从而它会在执行预定的下一条指令之前先进入异常处理流程。也就是说,异常在这些单元内部即可被发现并解决。 而对于中断,可以想象为想发起中断的是一套完全不同的电路(从时钟中断来看就是简单的计数和比较器),这套电路仅通过一根导线接入进来,当想要触发中断的时候则输入一个高电平或正边沿,处理器会在每执行完一条指令之后检查一下这根线,看情况决定是继续执行接下来的指令还是进入中断处理流程。也就是说,大多数情况下,指令执行的相关硬件单元和可能发起中断的电路是完全独立 并行 (Parallel) 运行的,它们中间只有一根导线相连,除此之外指令执行的那些单元就完全不知道对方处于什么状态了。

      [!NOTE] 如何从底层硬件的角度区分同步和异步?

      flashcard

      • 异常:以一个处理器传统的五级流水线设计而言,里面含有取指、译码、算术、 访存、寄存器等单元;假如某条指令的执行出现了问题,一定能被其中某个单元看到并反馈给流水线控制单元,从而它会在执行预定的下一条指令之前先进入异常处理流程。也就是说,异常在这些单元内部即可被发现并解决。
      • 中断:大多数情况下,指令执行的相关硬件单元和可能发起中断的电路是完全独立 并行 (Parallel) 运行的,它们中间只有一根导线相连,除此之外指令执行的那些单元就完全不知道对方处于什么状态了
    1. 编写应用程序的科学家(简称应用程序员)来自不同的领域,他们不一定有友好互助的意识,也不了解其他程序的执行情况,很难(也没必要)有提高整个系统利用率上的大局观。在他们的脑海里,整个计算机就应该是为他们自己的应用准备的,不用考虑其他程序的运行。这导致应用程序员在编写程序时,无法做到在程序的合适位置放置 放弃处理器的系统调用请求 ,这样系统的整体利用率还是无法提高。 所以,站在系统的层面,还是需要有一种办法能强制打断应用程序的执行,来提高整个系统的效率,让在整个系统中执行的多个程序之间占用计算机资源的情况相对公平一些。

      [!NOTE] 发明抢占式操作系统的动机是?

      flashcard

      电脑的使用者往往不了解其他程序的执行情况,很难(也没必要)有提高整个系统利用率上的大局观

    2. 计算机硬件在快速发展,内存容量在逐渐增大,处理器的速度也在增加,外设IO性能方面的进展不大。这就使得以往内存只能放下一个程序的情况得到很大改善,但处理器的空闲程度加大了。于是科学家就开始考虑在内存中尽量同时驻留多个应用,这样处理器的利用率就会提高。但只有一个程序执行完毕后或主动放弃执行,处理器才能执行另外一个程序。这种运行方式称为 多道程序 。

      [!NOTE] 多道程序出现的硬件背景是什么?

      flashcard

      • 内存容量在逐渐增大,处理器的速度也在增加
      • 外设IO性能方面的进展不大

      以往内存只能放下一个程序的情况得到很大改善,但处理器的空闲程度加大了

    1. 作业(Job)、任务(Task)和进程(Process) 历史上出现过的术语:Job、Task、Process Task、Process是Multics和UNIX等用于分时多任务提出的概念 进程是一个应用程序的一次执行过程。在操作系统语境下,任务和进程是同义词。 作业(目标)是围绕一个共同目标由一组相互关联的程序执行过程(进程、任务)形成的一个整体 参考:Difference between Job, Task and Process

      [!NOTE] OS 中,作业(Job)、任务(Task)和进程(Process)有什么异同?

      flashcard

      • 在操作系统语境下,任务和进程是同义词。
      • 作业(目标)是围绕一个共同目标由一组相互关联的程序执行过程(进程、任务)形成的一个整体
    1. 它是有歧义的,你也可以自己试试,如果只有这些产生式的话,上面的两个表达式都可以解析成正确或者错误的结果。

      [!NOTE] 如何根据语法解析表达式?

      flashcard

      例如 1+2*3

    2. 优先级是两个操作符之间的关系,例如*的优先级比+高,所以表达式1 + 2 * 3应该解析成语法树add (1 mul (2 3))(前序表示),不能解析成mul (add (1 2) 3) 结合性是一个操作符的性质,例如-是左结合的,所以表达式1 - 2 - 3应该解析成sub (sub (1 2) 3),不能解析成sub (1 sub (2 3))

      [!NOTE] 操作符的优先级与结合性有什么异同?

      flashcard

      都描述了多个操作数实例之间的解析顺序关系 优先级是两个操作符之间的关系,例如*的优先级比+高,而结合性是一个操作符的性质,例如-是左结合的

    1. 虽然 -2 和 2-3 里面的 - 意义不同,但 lexer 不知道这点(parser 才知道),所以它们都会用同样的 token kind - 表示。 但有时,可能需要后续阶段告诉 lexer(或 parser)一些信息,最经典的例子是 “typedef-name identifier problem”。

      [!NOTE] 词法分析中,关于 - 有什么需要注意的?

      flashcard

      取负与减法的区别

    1. 在 RISC-V 中,a0 和 a1 是 gcc 调用约定上的存储返回值的寄存器,返回值会按照其大小和顺序存储在 a0 和 a1 中。也就是说,如果你有一个 32 位的返回值,你可以放在 a0 中返回,如果你有两个 32 位的返回值,你就需要把它们分别放在 a0 和 a1 中返回。更多的返回值会全部放入内存返回,如约定好的栈的某个位置,这取决于函数调用约定。

      [!NOTE] RISC-V 如何返回多个值?

      flashcard

      放入内存返回

    2. 如果你增加了 TAC 指令,则可能需要在 TACFuncEmitter 类中增加生成相应指令的代码。

      [!NOTE] MiniDecaf 中,要增加 TAC 指令,需要做什么?

      flashcard

      1. 更新 tacinstr.py
      2. TACFuncEmitter 类中增加生成相应指令的代码
    1. 请注意 TAC 代码只是一种中间表示,并不需要像汇编语言那样有严格的语法。因此,同学们可以自由选择输出 TAC 代码的格式,只要方便自己调试即可。例如,你也可以将 _T2 = ADD _T0, _T1 输出成 _T2 = _T0 + _T1。

      [!NOTE] TAC 编写有什么规范吗?

      flashcard

    2. 可以把语义分析过程分为两个部分:分析符号含义和检查语义正确性。分析符号含义是指对于表达式中所出现的符号,找出该符号所代表的内容,这个工作主要通过检索符号表来实现。检查语义正确性指的是检查每条语句是否合法,比如检查每个表达式的操作数是否符合要求,每个表达式是否为语言规范中所规定的合法的表达式,使用的变量是否都经过定义等。程序代码通过了词法和语法分析,其语义未必正确,因此未必是合法的语句。不合法的语句具体含义在语言规范中没有规定,从而使得编译器无法确定这些语句的确切含义,所以检查语义的正确性是很有必要的。如果一个程序成功通过语义分析,则说明这个程序的含义对于编译器来说是明确的,翻译工作可以继续进行。

      [!NOTE] 编译器前端中,语义分析具体是做什么的?

      flashcard

      1. 符号表构建:声明了哪些标识符,待编译程序使用的标识符对应于哪个位置的声明。
      2. 类型检查:各语句和表达式是否类型正确。
    3. 语法分析树的建立可以说明所输入的 MiniDecaf 源程序在语法规范上是合法的,但是要进行有效的翻译,编译器还需要理解每个程序语句的含义。了解程序含义的过程称为语义分析。

      [!NOTE] 编译中,语义分析是指?

      flashcard

      了解程序(语法规范之外)含义的过程

    4. 词法分析和语法分析的最终结果是一棵跟所输入的 MiniDecaf 源程序相对应的语法树

      [!NOTE] 词法分析和语法分析(即编译器前端)的最终结果是?

      flashcard

      一棵跟所输入的源程序相对应的(抽象)语法树

    5. AST省略掉了完整的语法分析树中不必要的细节(例如条件表达式旁边的括号),有利于简化树的结构与后续对树的处理。

      [!NOTE] 抽象语法树与完整的语法分析树有什么区别?

      flashcard

      省略掉了完整的语法分析树中不必要的细节(例如条件表达式旁边的括号), 有利于简化树的结构与后续对树的处理

    6. 语法分析是在词法分析的基础上针对所输入的终结符串建立语法树,并对不符合语法规则的 MiniDecaf 程序进行报错处理。一般而言,这一步所生成的语法树并非表示了所有语法细节的语法分析树,而是只表示其树形结构的抽象语法树(Abstract Syntax Tree, AST)。比如,对于下面这一段简单的MiniDecaf 代码:

      [!NOTE] 语法分析具体是做什么的?

      flashcard

      在词法分析的基础上,建立(抽象)语法树,并分析之

    7. 词法分析的功能是从左到右扫描 MiniDecaf 源程序,识别出程序源代码中的标识符、保留字、整数常量、算符、分界符等单词符号(即终结符),并把识别结果返回给语法分析器,以供语法分析器使用。

      [!NOTE] 词法分析具体是做什么的?

      flashcard

      扫描源代码,识别出单词符号

    8. 编译器前端分为两个子任务,一是词法分析,二是语法分析。

      [!NOTE] 编译器的前端要完成哪些任务?

      flashcard

      1. 词法分析
      2. 语法分析
    1. sret指令的硬件逻辑: 恢复响应中断/异常 CPU Mode从S-Mode 回到U-Mode pc <-- spec CSR 继续运行

      [!NOTE] (RISC-V 中)从内核态切换到用户态(sret 指令)的硬件逻辑为?

      flashcard

      1. 修改特权级
      2. pc <- sepc CSR
    2. sscratch CSR 重要的中转寄存器 在特权级切换的时候,我们需要将 Trap 上下文保存在内核栈上,因此需要一个寄存器暂存内核栈地址,并以它作为基地址指针来依次保存 Trap 上下文的内容。 但是所有的通用寄存器都不能够用作基地址指针,因为它们都需要被保存,如果覆盖掉它们,就会影响后续应用控制流的执行。

      [!NOTE] sscratch 为什么有必要存在?

      flashcard

      • 需要一个寄存器暂存内核栈地址
      • 但是所有的通用寄存器都不能够用作基地址指针,因为它们都需要被保存
    3. 特权级切换后的硬件逻辑 sstatus 的 SPP 字段会被修改为 CPU 当前的特权级(U/S); sepc 会被修改为产生 Trap 的指令地址; scause/stval 分别会被修改成这次 Trap 的原因以及相关的附加信息; CPU 将当前特权级设为 S,跳到 stvec 所设置的 Trap 处理入口地址。

      [!NOTE] (RISC-V 中,)进入内核态的硬件逻辑为?

      flashcard

      1. sstatus.SPP
      2. sepc
      3. scause / stval
      4. CPU 将当前特权级设为 S?
      5. pc -> stvec 所设置的 Trap 处理入口地址
    4. CPU 对物理内存所做的缓存又分成d-cache和i-cache OS将修改会被 CPU 取指的内存区域,这会使得 i-cache 中含有与内存中不一致的内容 OS在这里必须使用 fence.i 指令手动清空 i-cache ,让里面所有的内容全部失效,才能够保证CPU访问内存数据和代码的正确性。

      [!NOTE] 修改 CPU 的 PC 指向的内存区域,需要注意什么?

      flashcard

      缓存为修改前所取,与修改后的不一致

    5. fence.i :用来清理 i-cache 注:fence.i是i-cache屏障(barrier)指令,非特权指令,属于 “Zifencei”扩展规范

      [!NOTE] RISC-V 中,fence.i 指令的功能为?

      flashcard

      清理 i-cache

    6. AMO: atomic memory operation

      [!NOTE] 计算机系统结构中,AMO 是指?

      flashcard

      atomic memory operation

    1. 我们并不能直接跳转到 app_n_start 直接运行,因为用户程序在编译的时候,会假定程序处在虚存的特定位置,而由于我们还没有虚存机制,因此我们在运行之前还需要将用户程序加载到规定的物理内存位置。为此我们规定了用户的链接脚本,并在内核完成程序的 “搬运” # user/lib/arch/riscv/user.ld

      [!QUESTION] user.ld 究竟需要怎么处理?

      flashcard

    1. 同样由于涉及寄存器的恢复,以及未来页表satp寄存器的设置等,userret也必须是一个汇编函数。

      [!QUESTION] 为什么涉及寄存器的恢复,以及未来页表satp寄存器的设置等就必须使用汇编函数?

      flashcard

    2. sscratch这个CSR寄存器的作用就是一个cache,它只负责存某一个值,这里它保存的就是TRAPFRAME结构体的位置

      [!QUESTION] 为什么 sscratch 保存了结构体的地址?

      flashcard

    3. sscratch这个CSR寄存器的作用就是一个cache,它只负责存某一个值,这里它保存的就是TRAPFRAME结构体的位置。

      [!NOTE] CSR sscratch 的功能为?

      flashcard

      一个cache,它只负责存某一个值

    4. w_stvec((uint64)uservec & ~0x3); // 写 stvec, 最后两位表明跳转模式,该实验始终为 0

      [!NOTE] RISC-V CSR xtvec 的最后两位表示?

      flashcard

      跳转模式

    5. csrr和csrrw指令是RV特供的读写CSR寄存器的指令。我们取用它的值的时候实际把原来a0的值和其交换了,因此返回时大家可以看到我们会再交换一次得到原来的a0。

      [!NOTE] RISC-V 中,csrrcsrrw 的功能分别为?

      flashcard

      读写CSR寄存器的指令。 我们取用它的值的时候实际把原来a0的值和其交换了,因此返回时大家可以看到我们会再交换一次得到原来的 a0

    1. 执行 ecall 这条指令的时候则会随着 CPU 当前所处特权级而触发不同的 陷入 情况。从表中可以看出,当 CPU 分别 处于 M/S/U 三种特权级时执行 ecall 这条指令会触发三种陷入。

      [!NOTE] RISC-V 中,ecall 指令触发的异常号为?

      flashcard

      当 CPU 分别 处于 M/S/U 三种特权级时执行 ecall 这条指令会触发三种陷入 异常号分别为 8,9,11 (为什么跳过10?)

    1. 如果测例仓库有所更新或者你切换了代码仓库的分支,你可能需要清理掉测例仓库原版的编译结果,此时需要执行 $ make -C user clean 它的作用基本等价于如下写法,但是更简便 $ cd user $ make clean $ cd ..

      [!NOTE] make -C <dir> 的功能为?

      flashcard

      切换到 <dir> 中执行 make

    1. .globl kern_entry # 使得ld能够看到kern_entry这个符号所在的位置, globl和global同义

      [!NOTE] .globl <symbol> 指令的功能为?

      flashcard

      将一个符号声明为全局符号。这意味着该符号可以在其他文件或模块中使用,而不需要额外的特殊处理 以便编译器知道该符号是在其他地方定义

    2. # The ,"ax",@progbits tells the assembler that the section is allocatable ("a"), executable ("x") and contains data ("@progbits").# 从这里开始.text 这个section, "ax" 和 %progbits描述这个section的特征# https://www.nongnu.org/avr-libc/user-manual/mem_sections.html.section .text,"ax",%progbits

      [!NOTE] .section .text,"ax",%progbits 表示什么?

      flashcard

      "ax",@progbits tells the assembler that the section is allocatable ("a"), executable ("x") and contains data

    3. /* small data section, 存储字节数小于某个标准的变量,一般是char, short等类型的 */ .sdata : { *(.sdata) *(.sdata.*) }​

      [!NOTE] .sdata 表示什么?

      flashcard

      "static data",但注意不是静态变量的静态,而是指常量 不可写 这些数据在程序启动时分配并在程序结束时释放,其内容在程序执行期间保持不变。静态数据可以包括全局变量、静态变量和常量等

    4. CSAPP 7.4 Relocatable Object filesAside Why is uninitialized data called .bss? The use of the term .bss to denote uninitialized data is universal. It was originally an acronym for the “block started by symbol” directive from the IBM 704 assembly language (circa 1957) and the acronym has stuck. A simple way to remember the difference between the .data and .bss sections is to think of “bss” as an abbreviation for “Better Save Space!”

      [!NOTE] 为什么把初始化为0(或者说,无需初始化)的数据段称作bss?

      flashcard

      "block started by symbol"

    5. "." 是SECTIONS指令内的一个特殊变量/计数器,对应内存里的一个地址。

      [!NOTE] .ld 中,. 是什么?

      flashcard

      SECTIONS指令内的一个特殊变量/计数器,用于临时储存内存地址

    1. It reduces activation memory required as it prevents the same copies to be on the tensor parallel ranks post all-reduce by replacing then with reduce-scatter and no-op operation would be replaced by all-gather. As all-reduce = reduce-scatter + all-gather, this saves a ton of activation memory at no added communication cost. To put it simply, it shards the outputs of each transformer layer along sequence dimension, e.g., if the sequence length is 1024 and the TP size is 4, each GPU will have 256 tokens (1024/4) for each sample.

      [!NOTE] 序列并行的原理是?

      flashcard

      it shards the outputs of each transformer layer along sequence dimension, e.g., if the sequence length is 1024 and the TP size is 4, each GPU will have 256 tokens (1024/4) for each sample It reduces activation memory required as it prevents the same copies to be on the tensor parallel ranks post all-reduce by replacing then with reduce-scatter and no-op operation would be replaced by all-gather. As all-reduce = reduce-scatter + all-gather, this saves a ton of activation memory at no added communication cost.

    2. Reduces the bubble of naive PP via PipeDream-Flush schedule/1F1B schedule and Interleaved 1F1B schedule.

      [!NOTE] Megatron-LM 使用了什么 PP 调度技术?

      flashcard

      PipeDream-Flush schedule/1F1B schedule and Interleaved 1F1B schedule

    3. Pipeline Parallelism (PP): Reduces memory footprint and enables large scale training via inter-node parallelization.

      [!NOTE] Megatron-LM 节点通信使用的是什么技术?

      flashcard

      PP

    4. Tensor Parallelism (TP): Reduces memory footprint without much additional communication on intra-node ranks.

      [!NOTE] Megatron-LM 节点内通信使用的是什么技术?

      flashcard

      TP

    5. In a simple transformer layer, this leads to 2 all-reduces in the forward path and 2 in the backward path.

      [!NOTE] Megatron-LM 的 TP 在一个简单的 transformer 层中,需要多少 collective 操作?

      flashcard

      • 2 all-reduces in the forward path
      • 2 in the backward path
    1. 我们有两种不同的可执行文件格式:elf(e是executable的意思, l是linkable的意思,f是format的意思)和bin(binary)。elf文件(wikipedia: elf)比较复杂,包含一个文件头(ELF header), 包含冗余的调试信息,指定程序每个section的内存布局,需要解析program header才能知道各段(section)的信息。如果我们已经有一个完整的操作系统来解析elf文件,那么elf文件可以直接执行。但是对于OpenSBI来说,elf格式还是太复杂了,把操作系统内核的elf文件交给OpenSBI就会发生版本2的悲惨故事。bin文件就比较简单了,简单地在文件头之后解释自己应该被加载到什么起始位置。OpenSBI可以理解得很清楚,这就是版本1的故事。

      [!NOTE] 可执行文件格式 .bin / .elf 在指定内存布局时有什么区别?

      flashcard

      .bin 文件在文件头之后解释自己应该被加载到什么起始位置

    1. what does -mcmodel=medany mean这选择了medium-any code model。这意味着程序和它静态定义的symbol必须在2GB范围

      [!NOTE] gcc --mcmodel=medany 表示什么?

      flashcard

      程序和它静态定义的symbol必须在2GB范围内

    1. 连接qemu:(gdb) target remote :1234Remote debugging using :12340x0000000000001000 in ?? ()

      [!NOTE] gdb 如何链接远程端口?

      flashcard

      (gdb) target remote <ip>:<port>

    2. 因为gdb和qemu是两个应用不能直接交流,比较常用的方法是以tcp进行通讯,也就是让qemu在localhost::1234端口上等待。

      [!NOTE] 在 QEMU 中使用 GDB 调试有什么困难?一般如何解决?

      flashcard

      两个应用不能直接交流 比较常用的方法是以tcp进行通讯,也就是让qemu在localhost::1234 端口上等待。

    1. 使用 where 命令查看程序出错的地方;(gdb) where

      [!NOTE] gdb 中,要查看程序出错的地方,可以使用?

      flashcard

      where 命令

    2. 在 gdb 提示符处键入help,将列出命令的分类,主要的分类有:aliases:命令别名breakpoints:断点定义;data:数据查看;files:指定并查看文件;internals:维护命令;running:程序执行;stack:调用栈查看;status:状态查看;tracepoints:跟踪程序执行。键入 help 后跟命令的分类名,可获得该类命令的详细清单。

      [!NOTE] gdb 命令行中,如何获取命令清单?

      flashcard

      • 在 gdb 提示符处键入help,将列出命令的分类
      • 键入 help 后跟命令的分类名,可获得该类命令的详细清单
    3. 在可以使用 gdb 调试程序之前,必须使用 -g 或 –ggdb编译选项编译源文件

      [!NOTE] 使用 gdb 前,需要如何处理源文件?

      flashcard

      -g–ggdb 编译选项编译源文件

    4. 数字%n的用法:数字表示的寄存器是按照出现和从左到右的顺序映射到用"r"或"q"请求的寄存器.如果要重用"r"或"q"请求的寄存器的话,就可以使用它们。

      [!NOTE] GCC 扩展内联汇编中,操作数引用 %n 的含义是如何决定的?

      flashcard

      按照出现和从左到右的顺序映射到用"r"或"q"请求的寄存器

    5. 如果有多行汇编,则每一行都要加上 "\n\t"。其中的 “\n” 是换行符,"\t” 是 tab 符,在每条命令的 结束加这两个符号,是为了让 gcc 把内联汇编代码翻译成一般的汇编代码时能够保证换行和留有一定的空格。对于基本asm语句,GCC编译出来的汇编代码就是双引号里的内容。例如: asm( "pushl %eax\n\t" "movl $0,%eax\n\t" "popl %eax" );实际上gcc在处理汇编时,是要把asm(...)的内容"打印"到汇编文件中,所以格式控制字符是必要的。

      [!NOTE] GCC 内联汇编中,要控制换行等格式,需要怎么做?

      flashcard

      如果有多行汇编,则每一行都要加上 "\n\t"

    6. 乱码列表通知编译器,有些寄存器或内存因内联汇编块造成乱码,可隐式地破坏了条件寄存器的某些位(字段)。

      [!NOTE] GCC 内联汇编中,乱码列表(globber list)是什么?

      flashcard

      括号内的第 4 部分(最后一部分) 通知编译器,有些寄存器或内存因内联汇编块造成乱码,可隐式地破坏了条件寄存器的某些位(字段)

    7. 以“memory”为约束条件,以表示操作完成后内存中的内容已有改变,如果原来某个寄存器的内容来自内存,那么现在内存中这个单元的内容已经改变。

      [!NOTE] GCC 扩展内联汇编中,"memory" 表示什么?

      flashcard

      操作完成后内存中的内容已有改变,如果原来某个寄存器的内容来自内存,那么现在内存中这个单元的内容已经改变

    8. 输入部分(input operand list):输入部分与输出部分相似,但没有“=”。如果输入部分一个操作数所要求使用的寄存器,与前面输出部分某个约束所要求的是同一个寄存器,那就把对应操作数的编号(如“1”,“2”等)放在约束条件中。在后面的例子中,可看到这种情况。

      [!NOTE] GCC 扩展内联汇编中,如果输入部分一个操作数所要求使用的寄存器,与前面输出部分某个约束所要求的是同一个寄存器,该怎么做?

      flashcard

      把对应操作数的编号(如“1”,“2”等)放在约束条件中

    9. GCC扩展内联汇编的基本格式是:asm [volatile] ( Assembler Template : Output Operands [ : Input Operands [ : Clobbers ] ])

      [!NOTE] GCC 扩展内联汇编的基本格式为?

      flashcard

      如下

    10. 输出部分(output operand list),用以规定对输出变量(目标操作数)如何与寄存器结合的约束(constraint),输出部分可以有多个约束,互相以逗号分开。每个约束以“=”开头,接着用一个字母来表示操作数的类型,然后是关于变量结合的约束。例如,上例中::"=r" (__dummy)“=r”表示相应的目标操作数(指令部分的%0)可以使用任何一个通用寄存器,并且变量__dummy 存放在这个寄存器中,但如果是::“=m”(__dummy)“=m”就表示相应的目标操作数是存放在内存单元__dummy中。表示约束条件的字母很多,下表给出几个主要的约束字母及其含义:

      [!NOTE] GCC 扩展内联汇编的输出部分的格式是怎样的?

      flashcard

      括号内的第 2 部分 "=<con>"(<var>), ...

    11. 选项 -Wall 开启编译器几乎所有常用的警告──强烈建议你始终使用该选项。

      [!NOTE] gcc 中如何开启常用警告?

      flashcard

      -Wall

    1. Click ... next to the Directory field and browse to the top level of your Git repository

      [!NOTE] Understand 的添加 git 仓库功能中,Directory 应该填什么?

      flashcard

      git 仓库要保存的目录

    1. 此外 clean_bss() 清空了 bss 段,注意,清空 elf 程序 .bss 段这一工作通常是由 OS 做的,而我们就只好自立更生了。

      [!NOTE] *清空 elf 程序 .bss 段这一工作通常是由什么完成的?

      flashcard

      OS

    1. 1995年,克里斯托弗·毕晓普证明了 具有输入噪声的训练等价于Tikhonov正则化 (Bishop, 1995)。 这项工作用数学证实了“要求函数光滑”和“要求函数对输入的随机噪声具有适应性”之间的联系。

      [!NOTE] 要求函数对输入的随机噪声具有适应性与函数的其他什么性质具有联系?

      flashcard

      光滑性,相当于函数不应该对其输入的微小变化敏感。

    2. 可以为每一层分别设置暂退概率: 常见的技巧是在靠近输入层的地方设置较低的暂退概率。 下面的模型将第一个和第二个隐藏层的暂退概率分别设置为0.2和0.5

      [!NOTE] 不同层的 dropout 取值一般有什么讲究?

      flashcard

      • 常见的技巧是在靠近输入层的地方设置较低的暂退概率
    3. 一些研究人员在测试时使用暂退法, 用于估计神经网络预测的“不确定性”: 如果通过许多不同的暂退法遮盖后得到的预测结果都是一致的,那么我们可以说网络发挥更稳定。

      [!NOTE] 测试时一般是否使用 dropout?

      flashcard

      如果训练时进行了激活值期望的修正,则一般不使用,即可近似 可能用于估计神经网络预测的“不确定性”

    4. 在标准暂退法正则化中,通过按保留(未丢弃)的节点的分数进行规范化来消除每一层的偏差。 换言之,每个中间活性值h以暂退概率p由随机变量h′替换,如下所示: (4.6.1)¶概率为其他情况h′={0 概率为 ph1−p 其他情况 根据此模型的设计,其期望值保持不变,即E[h′]=h。

      [!NOTE] 经典的 dropout 中,如何处理每一层的激活值?

      flashcard

      $h'=0;h/(1-p)$ 使期望值不变

    1. for i, row in run.history().iterrows():

      [!NOTE] WandB 如何从 run 中读取数据?

      flashcard

      run.history().iterrows()

    2. api.runs also accepts an order keyword argument. The default order is -created_at, specify +created_at to get results in ascending order. You can also sort by config or summary values e.g. summary.val_acc or config.experiment_name

      [!NOTE] WandB 中,api.runs() 的的排列顺序如何设置?

      flashcard

      可通过 order 参数设置,形如 "+created_at"

    3. Calling api.runs returns a Runs object that is iterable and acts like a list. By default the object loads 50 runs at a time in sequence as required, but you can change the number loaded per page with the per_page keyword argument.

      [!NOTE] WandB 中,api.runs() 的读取有什么特点?

      flashcard

      分批读取,默认每次读取 50 runs 可通过 per_page 参数设置

    4. This example script finds a project and outputs a CSV of runs with name, configs and summary stats. Replace <entity> and <project> with your W&B entity and the name of your project, respectively.import pandas as pdimport wandbapi = wandb.Api()entity, project = "<entity>", "<project>"runs = api.runs(entity + "/" + project)

      [!NOTE] WandB 中,如何通过 API 访问一个项目内所有 run?

      flashcard

      runs = api.runs(entity + "/" + project)

    5. The default history method samples the metrics to a fixed number of samples (the default is 500, you can change this with the samples __ argument). If you want to export all of the data on a large run, you can use the run.scan_history() method. For more details see the API Reference.

      [!NOTE] WandB 中,run.history() 输出的行数有什么特点?

      flashcard

      默认只 sample 500 个数据点 可修改 使用 run.scan_history() 获取所有数据点

    6. run.history()A list of dictionaries meant to store values that change while the model is training such as loss. The command wandb.log() appends to this object.

      [!NOTE] WandB 中,要获取 run 的中间过程,可以使用?

      flashcard

      run.history()

    7. run.summaryA dictionary of information that summarizes the run's results. This can be scalars like accuracy and loss, or large files. By default, wandb.log() sets the summary to the final value of a logged time series. The contents of the summary can also be set directly. Think of the summary as the run's "outputs".

      [!NOTE] WandB 中,要获取 run 的最终结果,可以使用?

      flashcard

      summary run.summary

    8. By default a single instance of an api object will cache all network requests. If your use case requires real time information in a running script, call api.flush() to get updated values.

      [!NOTE] wandb.Api 中,若要立刻使用更新后的值,可以使用?

      flashcard

      api.flush()

    1. Use the W&B Public API to update your config (or anything else about from a complete Run) after your Run. This is particularly useful if you forgot to log a value during a Run. Provide your entity, project name, and the Run ID to update your configuration after a Run has finished. Find these values directly from the Run object itself wandb.run or from the W&B App UI:

      [!NOTE] WandB 如何修改 config 值?

      flashcard

      wandb.Api()

    2. You can pass a nested dictionary to wandb.config(). W&B will flatten the names using dots in the W&B backend.

      [!NOTE] 向 wandb.config() 传入嵌套字典,会引发什么行为?

      flashcard

      使用点号 . 展平名称

    1. magic(bool, dict, or str, optional) The bool controls whether we try to auto-instrument your script, capturing basic details of your run without you having to add more wandb code. (default: False) You can also pass a dict, json string, or yaml filename.

      [!NOTE] wandb 中,要自动记录基本信息,可以使用?

      flashcard

      wandb.init(magic=...)

    2. reinit(bool, optional) Allow multiple wandb.init() calls in the same process. (default: False)

      [!NOTE] wanbd 中,要在同一个进程中多次启动 wandb,可以使用?

      flashcard

      wandb.init(reinit=True)

    3. At the end of your script, we will automatically call wandb.finish to finalize and cleanup the run. However, if you call wandb.init from a child process, you must explicitly call wandb.finish at the end of the child process.

      [!NOTE] 在子进程中调用 wandb.init() 后,需要注意什么?

      flashcard

      必须显式调用 wandb.finish()

    1. class numpy.finfo(dtype)[source]# Machine limits for floating point types.

      [!NOTE] NumPy 中,要获取浮点数数据类型信息,可以使用?

      flashcard

      np.finfo(dtype)

    1. When using kaiming_normal or kaiming_normal_ for initialisation, nonlinearity='linear' should be used instead of nonlinearity='selu' in order to get Self-Normalizing Neural Networks. See torch.nn.init.calculate_gain() for more information.

      [!NOTE] 使用 Kaiming 初始化时,需要注意什么?

      flashcard

      nonlinearity='linear' should be used instead of nonlinearity='selu'

    1. 自定制指令扩展。除了上述阐述的模块化指令子集的可扩展、可选择,RISC-V架构还有一个非常重要的特性,那就是支持第三方的扩展。用户可以扩展自己的指令子集,RISC-V预留了大量的指令编码空间用于用户的自定义扩展,同时,还定义了四条Custom指令可供用户直接使用,每条Custom指令都有几个比特位的子编码空间预留,因此,用户可以直接使用四条Custom指令扩展出几十条自定义的指令。

      [!NOTE] RISC-V 允许哪些自定义指令扩展的方法?

      flashcard

      • 四条Custom指令,每条Custom指令都有几个比特位的子编码空间预留
      • 预留了大量的指令编码空间用于用户的自定义扩展