0%

2021年终总结

疫情篇

不出意外,还是疫情控制下的一年,随着其他国家陆续放开疫情管控政策,国内经历了一波又一波的疫情反弹,特别是七月份南京那次疫情把我给折腾的。本来是跟本科一起踢球的一帮同学五年前约好了一场足球赛,深圳 -> 南京 -> 扬州,一切行程都特顺利,比赛也拿下了(主要是老年队手都年长了五岁,确实体力跟不上了),等我回深圳后就听说南京发生了疫情,而且当晚我就发烧了,吓得不行。后来社区知道我去过南京后半夜打电话告诉我马上有人来给做核酸,看起来要被隔离的节奏,等我灰溜溜爬起床后等了十几分钟还没来人就回拨问了下又说我这种情况只需要7天3检就好了。接下来十来天我的健康码就是时而变黄时而变绿,有时候起床时是绿码,到地铁站就变黄了,所以那几天每天起来第一件事就是看健康码好决定要不要去上班。

肆虐全球两年的新冠病毒经过变异已经变成一只传染性更强的怪兽了,但愿一切能尽早恢复正常。

Read more »

写在前面

现代操作系统原理与实现是上海交通大学并行与分布式系统研究所(IPADS)所长陈海波老师团队于2020年发表的大作,该书系统介绍了操作系统中经典的问题,并对学术界和工业界前沿的技术进行了详细描述。这么一本好书正是我特别需要的,补充自己在操作系统领域的贫乏知识。年初的时候借着公司内部项目组买书的红利,买了一本过来,但因为工作比较忙(太懒~~)一直放在书堆中吃灰,直到十月革命的枪声。。走远了。。直到十月中旬才想起来还有个压箱底儿的大宝贝儿一直没看,遂决定系统性研读这本操作系统教材。

第一章 – 操作系统概述

作为教材的第一章,一开始以一个Hello World程序可执行文件如何存储在计算机中、如何加载到内存并在CPU中运行、如何将“Hello World”这行字符输出到屏幕、两个Hello World程序如何同时在一个CPU中运行为切入点带着读者走进操作系统。

什么是操作系统?

总体而言,操作系统有两个职责:一是对硬件进行管理和抽象,二是为应用提供服务并进行管理。硬件和应用的新变化和新需求(新的硬件加入、应用对时延的要求等)驱动着操作系统不断演进。

操作系统简史

随着1946年世界公认的第一台通用计算机ENIAC诞生后,人们一直在思考如何管理计算机上的程序。GM-NAA I/O作为第一个操作系统具备了批处理的特性。从OS/360到UNIX,操作系统演进步入了分时与多任务操作系统阶段,UNIX中首次引入Shell,并通过管道等IPC方式将不同人物连接起来。UNIX和C语言的成功为两位作者赢得了1983年图灵奖。1991年,目前世界上最成功的、适用范围最广的开源操作系统诞生了,它的父亲是一位来自芬兰的年轻程序员Linus Torvalds。80年代,凭借着从施乐借鉴(剽窃)来的图形用户界面(GUI )操作系统的概念,乔布斯和盖茨将Macintosh和Windows操作系统成功应用到个人计算机中。现代操作系统一步步演进为当下我们在使用的各种计算机。人类的智慧勾勒出一部操作系统捡屎~

操作系统接口

系统调用接口 – 向内核请求服务。POSIX接口 – 为能同时在不同UNIX操作系统上运行的软件定义的一套标准的操作系统API,自由软件先驱RMS起的名字。领域应用接口:各个应用领域定义的应用开发接口,如汽车领域的AUTOSAR等。

Read more »

2020年是不平凡的一年,研三秋季学期末段便听说武汉出现疑似肺炎病毒,到后来波及全球,打乱了全世界的计划,同样包括我的一些计划。

本打算毕业典礼叫全家人一起去学校参加,给自己的求学生涯画上一个完美的句号,可惜计划赶不上变化。在家里呆了半年才返校,答辩也是线上完成的,在学校领了毕业证、处理了一些离校手续就在一周内匆匆离开。最想去学校的半年不得不在家里度过,回头想想确实很可惜,可惜一学期的校园时光,可惜没能跟生活了七年的南京的朋友们好好聚聚、道个别,可惜没能圆圆满满的完成毕业。校园生活已经翻篇,作为社畜的生活刚刚开始。

回顾在家里的几个月,最重要是事莫过于完成毕业论文,拖延症晚期的我在论文截止日期前一个月才开始写论文。现在想想幸好当时去了小冰家,那一个月在小冰妈妈的照顾下衣食无忧,潜心写论文。要是在自己家的话,还得每天自己做饭,又没人监督,怕是很难完成如此艰巨的任务(写的那么烂,还敢说艰巨。。)。当时的实验其实都做的差不多了,只是根据实验结果把文章写出来,结合一些学术论文和往年师兄们的论文,再开放一下思维、整理一下思路、拟好提纲,完成了雏形。后面修改着实让人心累,并且答辩前还在导师的要求下把实验工具以k8s原生的operator实现了,论文临提交前的那几天爆肝熬夜的日子真是让人头大。所幸最后顺利过关,也不枉三年的努力。

Read more »

实验

实验目标

  1. 搞清楚ps架构通信的时候是不是都会走QPI总线,跨numa node?
  2. PS在哪些cpu上跑也影响着通信的效率。尝试找到每个PS跑在哪几个cpu上

实验过程

k8s中cpuset的探索

为了找到PS具体使用的是哪几个cpu,尝试探索k8s对cpuset的使用。

k8s中,容器 cpuset 中的 CPU 数量与 pod 规格中指定的整数型 CPU limit 相等。只要保证pod属于 Guaranteed QoS(即limits和requests相等)且cpu的资源值为大于等于1的整数值,则该pod就会被cpu manager(从 1.10 版本开始,作为 beta 特性默认开启)分配两个独占的cpu。

Read more »

NCCL

概念

NVIDIA Collective Communication Library是一个GPU拓扑感知的,提供了多GPU collective通信的库。

NCCL只能支持到8张GPU的深度学习训练(参见

开发者文档nccl2.3

nccl2.4介绍文档中提到NCCL的All Reduce操作被用于百度ring-all-reduce和Horovod这两个使用ring的分布式训练框架中来获取GPU之间的full bandwidth。但同时提到ring的缺点是随着GPU数目的增长,延迟也成线性增加。为什么延迟会呈线性增加?,很简单,因为每个GPU每次发送完一个chunk就必须等下一个chunk从另一张GPU发过来,整个过程(包括reduce scatter和all gather)总共需要发送2(n-1)次,则延时为2(n-1)的倍数。见NCCL collective示意图

Read more »

网关

负责转发源ip地址的请求到目标ip地址。当路由表中将网关设置为0.0.0.0时,表示源ip地址直连网卡。

跨主机网络 - overlay network

flannel

整个过程参见张磊的极客课程深入剖析Kubernetes 32~35章节
基于UDP的跨主机通信的基本原理如图所示:

Read more »

前言

实习面试从三月份持续到五月份,一开始接受了腾讯的offer,后来去了阿里。从一开始面试头条备受打击,到后来得到满意的offer是一段很有价值的体验。

头条

头条一面

首先问了我的研究方向,吧啦吧啦讲了一大堆。接着问我k8s的scheduler实现,讲了过滤打分机制,这块内容不是特别清楚,接着问了docker的隔离和资源限制。问docker的启动流程的时候就懵了,不清楚具体的启动流程。后面给了道算法题:给定一段含有注释的c++代码,去掉注释,也没有顺利写出来。。
最后问CPU是怎么调度的、内存是怎么分配给进程的,都答得不好,卒。。

头条二面

哦,没有二面。。

阿里

阿里一面

主要是问简历上的东西。顺便问了下k8s service在底层怎么实现的(iptables),dockerfile和image的区别与联系。

阿里二面

笔试面。是搞混部的阿里韩堂面的,给了一道题目,top k的题目,恰巧前几天做过。。写了个快排思想的解题思路

阿里三面

李响大佬面的。开始聊了聊项目,慢慢聊起了gang scheduling,然后扯了一通。考虑集群中共有5个资源,有3个已经被占用了;此时job n申请3个资源,在gang scheduling的逻辑里面应该怎么做?最后问了在浏览器敲www.google.com会发生什么?从键盘输入到系统调用,到DNS,到tcp连接整个过程。

阿里四面

交叉面。感觉也是问简历上的东西。。

阿里五面

HR面。就是大是大非的问题,然后我问了下双十一的筹备工作,HR跟我说我有机会来感受的,也就是拿到offer了?

过了好长一段时间才收到阿里的意向书,最终还是选择了阿里。

Read more »

神经网络相关内容

神经网络

  • 多层神经网络需要非线性映射。如果全连接层没有非线性部分,只有线性部分,那么计算之后,线性的多层神经网络其实可以转换成一层的神经网络。故加入非线性层,多层神经网络才有意义。
  • 为防止使用sigmoid激活函数可能导致的梯度消失问题,激活函数一般取relu函数
  • 每个神经元都是由输入图片(或者语音等)和该神经元所在层的前面所有层的连接矩阵(如卷积核)决定的,所以一个神经元其实就是一个变量,而连接矩阵是一组固定的权值,输入图片的不同会使该神经元输出不同的值。因此模型才能预测不同的图片所属的不同分类。我们保存的模型其实主要就是模型的连接矩阵,这也是神经网络训练过程中需要学习的

提高验证准确性的方法

  • 增加数据集:Adding more data augmentations often reduces the gap between training and validation accuracy. Data augmentation could be reduced in epochs closer to the end.
  • 初始学习率设置大一点:Start with a large learning rate and keep it large for a long time. For example, in CIFAR10, you could keep the learning rate at 0.1 for the first 200 epochs and then reduce it to 0.01.
  • batch size不能太大:Do not use a batch size that is too large, especially batch size >> number of classes.
    • batch_size增大,会使训练速度加快,不过太大会导致learning rate不好调,因为lr和batch size之间不是线性关系
    • batch_size太小,模型训练的慢
Read more »

1. 模型

1.1. Graph and Session

在分布式参数服务器架构训练中,tf.train.replica_device_setter(ps_tasks=3)可以用来指定将tf.Variable的放置位置,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
with tf.device(tf.train.replica_device_setter(ps_tasks=3)):
# tf.Variable objects are, by default, placed on tasks in "/job:ps" in a
# round-robin fashion. And only Variable ops are placed on ps tasks
w_0 = tf.Variable(...) # placed on "/job:ps/task:0"
b_0 = tf.Variable(...) # placed on "/job:ps/task:1"
w_1 = tf.Variable(...) # placed on "/job:ps/task:2"
b_1 = tf.Variable(...) # placed on "/job:ps/task:0"

input_data = tf.placeholder(tf.float32) # placed on "/job:worker"
layer_0 = tf.matmul(input_data, w_0) + b_0 # placed on "/job:worker"
layer_1 = tf.matmul(layer_0, w_1) + b_1 # placed on "/job:worker"

# or place worker
with tf.device(tf.train.replica_device_setter(
worker_device='/job:worker/task:'+task_idx,
clustercluster=cluster)):
# build your model here as if you only were using a single machine
with tf.Session(server.target):
# train your model here

tf.Variable 对象默认是放在ps上的,也只有Varibale是放在ps上的

ps上面只是存储了模型的参数,多个ps会将模型的参数拆分之后分别进行存储,workers计算参数更新之后,会将相应的参数发送到对应的ps上去。

tf.train.replica_device_setter会返回一个device function,用于with tf.device(device_function):在Operation对象构造时自动给Operation对象

Read more »

Python

  • Use ‘’.startswith() and ‘’.endswith() instead of string slicing to check for prefixes or suffixes.

    startswith() and endswith() are cleaner and less error prone:

    Yes: if foo.startswith(‘bar’):

    No: if foo[:3] == ‘bar’:

  • When catching exceptions, mention specific exceptions whenever possible instead of using a bare except: clause:

    1
    2
    3
    4
    try:
    import platform_specific_module
    except ImportError:
    platform_specific_module = None

    *和**的用法

    *args 表示接收一个tuple作为参数;\**kw 表示接收一个dict作为参数

    1
    2
    3
    4
    5
    6
    7
    8
    def sample(a,*args,**kwargs):
    print “a is {}”.format(a)
    print “*args is a tuple {}”.format(args)
    print “**kwargs is a dictionary {}”.format(kwargs)
    >>> sample(1,2,3,4,name=”rahul”,age=26)
    a is 1
    *args is a tuple (2, 3, 4)
    **kwargs is a dictionary {‘age’: 26, ‘name’: ‘rahul’}
Read more »