TensorFlow with CUDA安装在Ubuntu的踩坑记录

最近研究TensorFlow,需要开发环境,需要安装一个。我选择了在Ubuntu上使用docker来进行TensorFlow开发环境。因为使用docker是目前最方便搭建开发环境的工具。

安装步骤官方文档说明得比较详细。其实用docker安装环境没有什么可以说的,能会有问题么?如果你使用cpu版本基本不会有问题的。但是如果你使用的是GPU版本。那你还要安装CUDA环境和需要这些支持。我选择了使用CUDA9.1,安装教程在这。在CUDA9.1的下载安装我选择了从网络deb的方式

不过安装后,运行测试程序(nvidia-smi)或在运行nvidia-docker失败。

 
Failed to initialize NVML: GPU access blocked by the operating system

nvidia-docker failed to initialize nvml: driver/library version mismatch

后来发觉这是驱动的安装问题。我使用的是这里的下载的驱动文件,你可以在www.nvidia.com/drivers按照你显卡型号选择驱动,我发觉最后下载的文件都一样的。下载的文件名称NVIDIA-Linux-x86_64-390.48.run。使用

sudo sh NVIDIA-Linux-x86_64-390.48.run

进行安装,途中会有些报错,不理会继续继续。但是安装出来后,cuda不能正常运行。查询google。最后发现原来官方说这个驱动在ubuntu上需要手动安装。不要直接运行run文件。

#这里先卸载之前安装的驱动。
sudo apt-get remove --purge nvidia-390 nvidia-modprobe nvidia-settings
#重新安装驱动,虽然安装过程中有报错,不过后来测试运行暂时没有发现问题。
sudo apt-get install nvidia-390 nvidia-modprobe nvidia-settings

经过这一卸载,再安装就成功了。幸福来得有点突然。哈哈哈。

还有一个地方需要注意的是,nvidia-docker的安装需要指定的docker版本,而且这个版本必须是精确的版本。不能高于或在一个小升级的版本。而且这个版本不是稳定版本来的。我这次需要的是Docker version 18.03.1-ce, build 9ee9f40版本。不过你的版本不对他是不会继续给你安装的。

下边给几个用于检查安装好的环境

cat /proc/driver/nvidia/version
NVRM version: NVIDIA UNIX x86_64 Kernel Module  390.30  Wed Jan 31 22:08:49 PST 2018
GCC version:  gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)

ls -l /dev/nvidia*
crw-rw-rw- 1 root root 195, 254 May  3 10:00 /dev/nvidia-modeset
crw-rw-rw- 1 root root 243,   0 May  3 09:03 /dev/nvidia-uvm
crw-rw-rw- 1 root root 243,   1 May  3 10:00 /dev/nvidia-uvm-tools
crw-rw-rw- 1 root root 195,   0 May  3 10:00 /dev/nvidia0
crw-rw-rw- 1 root root 195, 255 May  3 09:03 /dev/nvidiactl
(我安装驱动失败的时候这里只有两个设备,/dev/nvidia-uvm和/dev/nvidiactl)

lspci | grep -i nvidia
01:00.0 VGA compatible controller: NVIDIA Corporation GK208 [GeForce GT 730] (rev a1)
01:00.1 Audio device: NVIDIA Corporation GK208 HDMI/DP Audio Controller (rev a1)

cat /proc/driver/nvidia/gpus/0000:01:00.0/information
Model: 		 GeForce GT 730
IRQ:   		 34
GPU UUID: 	 GPU-????????-????-????-????-????????????
Video BIOS: 	 ??.??.??.??.??
Bus Type: 	 PCIe
DMA Size: 	 40 bits
DMA Mask: 	 0xffffffffff
Bus Location: 	 0000:01:00.0
Device Minor: 	 0

大家别笑我的GPU太差。真实使用的时候需要租用云服务器的GPU。

修复mac OS X的Docker: No Space Left on Device

mac os x的docker现在比较好用,虽然macOS都是POSIX系统。但是多少都和linux系统有点不一样。所以我实验一些新软件系统的时候很多时候还是需要linux系统,以前多数使用虚拟机进行。现在喜欢用docker了。虽然mac上的docker也是运行在虚拟机上的。但是运行效果和在linux上没有什么区别。但有一个问题困扰了我很久。就是经常出现No Space Left on Device。明明我的磁盘还有很多空间。就是老出现这句提示。原来的处理方式,是删除一些不需要的image。最近由于剩下的images都是需要的,删无可删了。

只能上网找解决方法。发现这个问题还是不好处理的。最后虽然成功处理了。大家发觉处理的方式和网上说的有点不一样,所以记录下来。不能说别人的方法错误,只能说明我更加黑仔。

首先,这个不够磁盘空间的问题产生有几种情况的。

1 虚拟机的虚拟磁盘空间不够了。

2 是虚拟机的磁盘分区导致空间不够。(估计大部分人都是这个问题,我就是这个问题导致的。)都不知道为什么docker这么傻逼,生成一个虚拟磁盘是64G的。但是在这个磁盘上在分配一个18G的分区进行使用,超过18G就不能用了。超级傻逼。

现在讲处理方法。

继续阅读“修复mac OS X的Docker: No Space Left on Device”

golang 与cgo的跨平台编译

golang语音本身是支持跨平台编译的,只要在编译的时候添加相应的选项就可以了。不过有一个问题是不支持带有cgo的程序。如果需要支持cgo还需要配置编译cgo的环境,如果一个带cgo的程序需要编译成多个平台的支持,那是一件痛苦的事情,或者需要编译成非开发机本机运行版本,也是一件麻烦事。特别是开发嵌入式arm程序的时候就编译环境的配置就特别麻烦。不过现在有万能的docker对配置进行了简化。

由于工作需要,之前自己做了一个docker编译go 和cgo在android上运行的images,不过当时是手工制作images,并没有记录制作步骤和写下dockerfile。由于目前go和android的版本升级比较快。所以原来的docker images已经不合时宜了。不想再自己去做这个images了。在网上搜索了一个Go CGO cross compiler这个docker images比自己做的强大很多,支持很多平台的编译。使用起来比较方便。大家可以看看说明就可以了。非常方便。

由于这个docker的操作非常自动,可以说太自动了。例如,编译的项目必须在git上,自动下载项目和项目相关的库。对于一些不在git上的公司内部项目不是很友好。而且好像每次都重新下载项目和关联的代码库。导致编译速度非常慢,本来就是比较慢了。所以我没有使用它提供的的xgo工具。只使用它的docker images。

这个docker images的使用方法官方并没有说明。不过通过其dockerfile可以窥探其秘密。

进入这个docker的命令是:

docker run -it –entrypoint /bin/bash  karalabe/xgo-latest

因为这个docker设置了entrypoint是根目录的build.sh,需要把它替换成bash。这个docker的go path位于/go目录中,代码需要放在/go/src目录中。然后可以运行/build.sh XXXX 进行项目编译。当然可以归宿主机的代码映射到docker目录中并自动运行编译那时最方便的。

docker run –rm -it \
-v “$PWD”:/build \
-v “$PWD”/vendor:/go/src \
-v “$PWD”:/go/src/XXXXX \
karalabe/xgo-latest XXXXX

#XXXX代表你的项目目录名称。这里把项目需要包含的依赖包也一并映射到docker的/go/src中。

这样就可以很方便编译出各个平台运行的版本可执行文件,包括windows,macOS,iOS,android,linux,arm等。不过大多数我们并不需要编译这么多平台的版本,很多时候我们只需一个版本就够了。这样可以节省很多的编译时间。

docker run –rm -it \
-v “$PWD”:/build \
-v “$PWD”/vendor:/go/src \
-v “$PWD”:/go/src/XXXXX \
-e TARGETS=android/arm \
karalabe/xgo-latest XXXXX

这样写就可以只编译android的arm的版本。具体TARGETS支持什么参数,请参考官方说明。

使用docker重建Gitlab服务

新年假期回到公司,就发现一个噩耗,就是代码服务器意外关机,重启不成功。虽然我知道linux的机器意外关机会造成不可以预知的损坏,但是在10多年的linux使用生涯中还是真的未遇过。这次终于给我遇上了。

虽然数据在年前已经备份过了。不过我想到的是如果这台机救不回来,要我重新安装这个gitlab服务就真的疼苦了。虽然当初安装的时候有把关键点都记录下来。不过再安装一次的确痛苦。关键是迁移数据的问题。我还发现一个问题就是我没有记录当时安装的gitlab的版本,低级错误。不过经过维护部门的努力,机器是可以重新启动,gitlab服务也正常。不过在等待维护部门的修复,就等待了好几天。好在影响不大,其实这些东西本应不用我操心的。不过公司一共4个开发团队,就我一个团队使用代码管理。其他几个部门还是原始社会的手工管理。所以这个代码服务器想移交去维护部门都不行。

虽然这次救活了,但是我还是需要准备万一下次再出问题的时候,修复不了机器的时候做好准备了。作为快速搭建服务,首选是使用docker进行部署。目前已经有人做好了docker-gitlab的image镜像。目前这个image的版本使用gitlab 7.8.1,不过我们使用的gitlab的版本是6.6.5的版本。不知道数据库是否可以平滑升级。

找了一台Ubuntu 14.04机器进行测试。其实使用这个docker-gitlab的container比较简单,他的github页面说明比较详细。如果新建的gitlab服务,参照他的说明就可以了。比较简单。但是有一个坑,这个可能是docker-compose(原有的fig)的bug。

继续阅读“使用docker重建Gitlab服务”