搭建个人综合工作站

计划 & 需求

去年春节前,出于某些原因,需要 DIY 一台高性能的工作站,这台机器定位是处理多任务的综合工作站,并非单纯用来做深度学习,所以投入不会全砸显卡,需求大致如下:

  • 7*24h 开机:服务器主板 / Xeon CPU / ECC 内存
  • 大量 crontab 定时任务:CPU 核心数量较多 / 内存容量较大
  • 大量并发爬虫:硬盘空间要大,网速要快
  • 远程访问支持:有公网 IP 和域名,配合手头多个 VPS 进行分布式计算
  • 深度学习支持: 高性能 GPU
  • 较为可靠的数据存储:raid / 大内存缓冲
  • Linux 系统 CLI 环境: 全部使用命令行工具,开启 X11 forward 支持

选型

根据需求,大致确定了主要部件:

主板

超微 x10dai,主要是奔着雷电接口去的,论价位确实比较实惠,但只有 3 个 PCIe,而且第三个槽位置有限,插长显卡会挡住不少其他接口,因此扩展性一般。相比之下,超微的 7048 准系统可能更好。

CPU

双路 E5 2696 v4,据说和 E5 2699 v4 的参数完全一样,就是换了个马甲,主要看中核心多,并行支持好,且支持 ECC 内存,进一步提高稳定性。如果只搞机器学习,则不需要这么强的 CPU,普通 i7 就可以满足大部分需求。除了 i7 之外,最近 AMD 出的 r7 1800x 也是非常好的选择,3000 多块稍微超一下频 8 颗核心都可以到达 4.2G 以上,比大多数 i7 强了。

内存

RECC DDR4 2400MHz 16G 4 条,要注意的是,4 条内存每个 CPU 分 2 条,要插同色插槽。

显卡

Titan X pascal,虽然很贵,但显存足够大,能处理更复杂的模型。如果是现在的话,肯定选择 1080ti 了,价格低了近 40%。需要注意主板上显卡之间的距离,多卡距离近的情况下,公版显卡散热更有优势。

硬盘

三星 EVO 850 500G SSD,装系统其实完全用不了这么多。分区方面,分一个/swap,如果用 UEFI 启动模式再加一个 UEFI 分区即可, 其他东西都可以放在一个分区,这样也不用操心如何确定分区大小了。三星这个 SSD 速度非常一般,价格却一点不便宜。

散热器

海盗船 H100i v2 水冷,自带的风扇不是很静音,散热效果还是不错的,就是冷排很大,要考虑机箱是否有位置安装。

电源

海盗船 RM1000x,原计划最多双显卡,这样电源刚好够用,如果考虑 3 卡以上,应该直接该上 1500W 电源。也有人说可以淘服务器电源,价格不贵量又足。

配置单

配件 型号 数量 单价 总价
CPU E5 2696 v4 2 9500 19000
内存 金士顿 RECC DDR4 2400MHz 16G 4 1000 4000
硬盘 三星 EVO 850 500G 1 1200 1200
主板 超微 x10dai 1 2600 2600
显卡 Titan X pascal 1 10000 10000
机箱 海盗船 780T 1 1000 1000
散热器 海盗船 H100i v2 2 1000 2000
电源 海盗船 RM1000x 1 1200 1200
雷电卡 华硕 ASUS Ex II 1 1000 1000
总计       42000

DIY

以前从未自己动手装过机,第一次装机差不多花了 8 个小时,整体还算顺利。主要的体会是,遇到问题一定要先看说明书。 机箱的选择也很重要,我这个机箱上的铜柱位置和主板上螺钉位置不一致,虽然都是 E-ATX 的,但只有 3 个螺钉对得上。机箱上的风扇位也要提前考虑到,否则水冷冷排就没地方放了。 除此以外,机箱内走线需要花点心思,主板跳线和风扇因为空间狭小,也比较花时间。 DIY 需要足够的耐心和细心,一次能安装到位是最好的,调整和拆卸更费事。

系统

Gentoo,我从 08 年开始用 Gentoo 直到换 Mac,整整 5 年,一直稳定可靠,尤其是各类开发工具,ubuntu 倒是经常有小 bug。这台机器性能足够强大,编译安装不用等待太久,Gentoo 编译慢的缺点也不是问题了。CPU 满载编译内核几十秒就可以完成,而在笔记本上通常要半个小时。 尽管熟悉 Gentoo,从 stage-3 订制到一个用起来顺手的状态,还是花了一些时间。也遇到了不少常见问题,比如循环依赖、python-exec 指向错误、ssh 相关配置、内核配置等。遗憾的是,我购买的华硕雷电卡没有 Linux 驱动,我花了大量时间确认了这一点。 Gentoo 很小众,没有 Gentoo 下安装 Tensorflow、CUDA 和 cuDNN 的教程。我先后尝试通过 portage(Gentoo 包管理器)、layman(portage 之外的第三方扩展包)以及手动编译 tensorflow,均不成功。最后先把 Nvidia driver 和 cuDNN 的两个 run 包下载到本地,手动一个个运行才安装成功。tensorflow 则使用 pip install tensorflow-gpu 进行安装。 使用 4.9 版本内核,开启了 docker、bbr、zfs、nvme、uefi 等功能支持,同时优化了系统的 ulimit 参数,从省 SSD 的角度出发,把系统中主要的几个 tmp 和 cache 目录都挂载到内存里了,也给 ZFS 分配了很多内存做缓冲。

网络

升级到了联通 200M 光纤,上行速率大约 60~70M,远程连接速度比阿里云的 5M 要强太多。但是有两个问题:第一,联通光猫负责拨号,却不支持端口映射和 DMZ,无法从外部访问;第二,虽然有公网 IP,但这个 IP 是动态的,大约几天就变化一次。 手头有个阿里云 5M 带宽的 VPS,首先想到用它做一个中转。听说 ngrok 不错,然而我部署时总是报错。根据这篇教程, 通过 ssh 隧道的方式,在工作站上启动一个 autossh 的服务连接阿里云并绑定某一端口,这样远程访问工作站时直接 ssh 那个端口即可。但是这样的话,带宽就限制为 5M 了,始终有些不爽,一次偶然的机会看到了破解联通光猫的完整教程 ,把光猫改成桥接模式,从路由器拨号,这样就能使用路由器进行端口映射和 DMZ 了,终于可以直接进行 ssh 访问了。 动态 IP 的问题,有不少解决方案,一开始使用 Netgear 路由里自带的 DDNS 功能,注册一个 netgear 账号,路由会自动把本机当前 IP 更新到 netgear 提供的一个子域名上,然而用了几周后出现了一次更新失败。因此转向了 dnspod,从 godaddy 上买了一个域名,然后把域名的 Nameserver 改成 dnspod 提供的 Nameserver 地址,等待生效后,在工作站上跑一个定时更新 ip 到 dnspod 的脚本即可,然后 dnspod 会负责把新 ip 同步到 DNS 记录中。

硬件升级

过年后对工作站硬件进行了几次升级。添加的硬件如下:

配件 数量 单价 总价
超微雷电卡 1 2000 2000
西数 NAS 红盘 4T 4 0 0
Titan x pascal 1 9300 9300
金士顿 RECC DDR4 2400MHz 16G 4 1000 4000
intel 750 1.2T SSD 1 4300 4300
Total     19600

加上之前的配置,整套价格 6W 多一点,其中西数硬盘是从原来的硬盘阵列中拆下来的,就不计价格了。主要的坑有:

雷电卡

Linux 下仍然识别不出来,反复调整内核模块也是无效,只能静等以后更新了。

硬盘阵列

因为雷电卡仍然不 work,只能把里面原有的 4 块硬盘取出,把机箱带的硬盘笼安回去,通过 zfs 做了 raidz,数据自然是要提前备份。zfs 目前能支持 4.9 版本的内核,使用起来意外的简单便捷。安回硬盘笼导致原先的水冷冷排要移动至机箱下方,管道长度和机箱下方的风扇位都是刚刚好,真是万幸。

第二块显卡

购买时 1080ti 快出了,不过考虑到将来换新机时,双 Titan X 可以组个 SLI 当娱乐机打打游戏,所以又入手了一块 Titan X。x10dai 的 Bios 中必须调一下设置 才能识别到第二块卡,否则会报错误。添加显卡的另一个麻烦是机箱里的水冷管和电源线需要大规模调整。

intel 750

这货读写速度比三星 EVO 快了 5 倍以上,正好又能利用第三个 PCI E 插槽,所以直接入手了。安装不难,但是做系统迁移整整花了一个周末。首先 Bios 里要设置该 SSD 的 PCIE 模式为 UEFI 才能识别到设备,然后对新 SSD 重新分区,使用 rysnc 进行镜像同步。设置 bootloader 引导,至少可以采用 grub2 / efibootmgr / efi shell 三种方式添加引导记录,但是这块硬盘有个问题,设备启动到可被识别需要大约 5 秒时间,直接引导会出现找不到 root 分区的问题,即使刷了最新固件也不行,该问题很隐蔽,重新编译了很多次内核,尝试了多种参数设置才定位到。给内核添加 rootwait 启动参数不知为何会无限等待。使用 gentoo 提供的 genkernel 生成 initramfs 也无法正确引导,最后发现使用 dracut 做 initramfs 并添加 rootwait 参数可以 work。整体的启动时间是长了一点,考虑到工作站长期不重启倒也能接受。系统迁移到新 SSD 之后,原来的 SSD 计划做成 ZFS 的缓存,这样一方面保护磁盘,另外也提高了读写性能。

USB 3.0

主板上有个 usb 3.0 接口,装显卡时不慎把线碰松了,结果上电没反应,此错误十分隐蔽,也浪费了许多时间去拔插其他零件排除故障。

云服务

实现公网访问后,基本上可以代替云主机跑各种云服务了。常用的有:

nextcloud

一个云存储服务,移动端 app 做的也不错,需要做一些配置,整体比较稳定,速度也不错,而且有一定的可扩展性。随时随地有这样一个私有云网盘还是非常方便的,还可以给亲朋好友开账户共享文件。

superset

airbnb 的数据可视化工具,可以轻松做出不少优秀的图表,和数据库衔接得很好,能用来做一些简单挖掘和可视化工作。

jupyter

很流行的一款 web REPL,类似于 ipython,支持的语言更多,代码和文档可以方便地整合在一起,类似于 Knuth 的文学编程概念。

znc

IRC server,以前是开在阿里云上的,现在大多数服务都不用阿里云了。有了个人的 znc,就能 24 小时接收指定频道的消息,还可以方便地和 irssi、emacs 的 erc、移动端的 mutter 等客户端集成。

mldonkey

Linux 下的优秀下载工具,支持 BT、ed2k 等下载协议,资源占用极少,稍微配置一下就能跑满带宽。可以通过 Web 界面进行控制,为远程管理提供了极大便利。

emacs

emacs daemon 配合 screen 使用,就是一个高度灵活的云工作环境。无论在什么地方,用什么设备,ssh 连接后,执行 screen -rd 就能回到之前的工作环境中。从此不再需要购买 rmbp 这种高大上的笔记本了,只需要一块大屏幕,哪怕接个树莓派,都可以十分流畅地工作。

redis

一方面用作多机分布式任务的消息队列,另一方面也可作为 nextcloud 的缓存,减少磁盘读写。

虚拟化

多核心 CPU 和较大的内存,使虚拟化有了实际意义

docker

用来部署确实无比方便,但是镜像多了也很吃硬盘空间。阿里云的 docker hub 比较快,也可以自己搭建。

Esxi

比操作系统更底层的虚拟机,可以高效地同时跑 windows / Linux / MacOS 等多个操作系统,可玩性不错,如果是多人共享工作站,这是个很好的解决方案。

后记

这台机器硬件配置差不多定型了,以后升级无非是再增加一些内存和硬盘。如果没有那么多其他任务要跑,组建一台 4 卡深度学习工作站,会便宜很多,比如 i7 / AMD r7 + 4 块 1080ti,这样的配置大概 3W 多可以搞定。如果还在观望,或者对机器学习只是业余爱好,想先搞个经济实惠的玩一下,采用二手 E5 / i7 + 1070 这样的组合,最低 6000 元可以搞定,性能其实也不差,足以应付大多数 kaggle 项目了。目前来看,商业机器学习云服务还不够成熟,阿里云每个月 9000,性能非常一般,采用的 k40m TFLOPS 性能不如 1070,而亚马逊虽是 4 卡,每块显卡只有 4G 显存,从国内 ssh 连接也卡得一塌糊涂。组装物理机虽然折腾,从性价比角度还是完胜云服务的。