服务器配置

  • ubuntu16.04服务器版
  • anaconda
  • cuda
  • tensorflow :::info

    安装

    win10安装教程linux安装教程TensorFlow官网指导相关软件版本的对照表,页面底端如果不使用GPU的话,只需要cmd中一行pip install tensorflow就行了。不过需要注意的是,tensorflow的默认安装版本是1.31,而1.31对应的python版本最高是3.6,如果你的python版本过低或过高,在导入TensorFlow包时都会出错。 :::

  • frp:内网穿透 :::info 如果服务器处于局域网内,那么当终端离开局域网后是无法连接服务器的,这时我们就要借助内网穿透。内网穿透可以将内网中服务器的局域网ip和端口映射到外网ip和端口。具体实现时,你需要一台云服务器,然后在上面通过开源的frp搭建一个反向代理。 :::

连接服务器

阿里云服务器

登录地址:https://homenew.console.aliyun.com/
登陆后可以直接通过内部工具链接服务器
image.png

即使忘记root密码,也可以通过网页登录后链接,然后sudo su获取root权限,接着passwd重置密码。

终端配置

以下都是通过ssh协议中的口令登录方式完成连接。

linux/mac

linux/mac系统集成了ssh工具,所以可以在shell中直连服务器。

win10

如果是windows系统,那么我们需要一个ssh工具来完成ssh连接。xshell或者putty都可以胜任。

免密登陆

ssh同时还提供了公钥登录的方式。这点在上面的背景知识中已经介绍了。
具体的做法就是将你的公钥存储在服务器的ssh信任列表中中。

  1. 生成秘钥
    1. # -P表示需要密码,-P ‘’表示空密码
    2. ssh-keygen -t rsa -P ''
    3. 之后系统会提示输入生成的密钥文件的文件名,可以输入任意名称,比如id_rsa
  1. 找到自己的公钥,没有的话通过ssh-keygen 生成。然后通过 scp 命令传输公钥到服务器中。

通过服务器进行深度学习 - 图2

  1. 在服务器中将刚刚的公钥添加到ssh信任列表。然后即可免密登陆了。
    1. cat -n id_rsa.pub>> ~/.ssh/authorized_keys # -n参数代表在末尾添加,如果列表为空,可以不加
    2. cat ~/.ssh/authorized_keys # 显示列表中的公钥,当然,也可以用vim

:::info 如果还是无法免密登陆,有以下几个可能

  1. 服务器端的 .sshauthorized_keys 的权限不匹配。
    • 一般修改.ssh文件夹的权限就够了

chmod 700 /home/skyler/.ssh

  • 如无必要不作修改

chmod 600 /home/skyler/.ssh/authorized_keys

  1. ssh配置文件未开启秘钥登陆

vi /etc/ssh/sshd_config

  1. #RSAAuthentication yes
  2. #PubkeyAuthentication yes
  3. #AuthorizedKeysFile %h/.ssh/authorized_keys

取消以上代码的注释符,之后重启ssh服务: service ssh restart

  1. 如果是使用putty终端登陆服务器,需要在Connection->SSH->Auth中添加对应的私钥。
  2. 如果是阿里云的服务器,应当通过阿里云的控制台创建密钥对,以本地为windows为例:创建密钥对后在控制台重启服务器,然后通过puttygen将下载的私钥转化为ppk格式,最后在putty的Auth中添加私钥。ok~ :::

服务器使用代理

注意,这里说的是让服务器使用代理客户端,而不是配置服务端。
参考博客:Ubuntu Server 18.04 LTS 使用Shadowsocks-ShadowsocksR访问互联网

安装git

  1. apt install git

安装ssr

通过一键脚本安装ssr

  1. wget https://github.com/the0demiurge/CharlesScripts/raw/master/charles/bin/ssr

这个脚本算是写的比较完善了,里面封装了 SSR 的安装、配置、启动、关闭等功能。
为了方便操作,我们将脚本放进/usr/local/bin中(里面的程序将自动加入path中,可以在任意位置执行)

  1. sudo mv ssr /usr/local/bin
  2. sudo chmod 766 /usr/local/bin/ssr

然后任意位置执行

  1. ssr install #自动安装到 $HOME/.local/share/shadowsocksr
  2. ssr help # 获取帮助信息
  3. ssr config # 编辑配置信息,如下
  4. {
  5. "server": "{your-server}",
  6. "server_ipv6": "::",
  7. "server_port": 12345,
  8. "local_address": "127.0.0.1",
  9. "local_port": 1080,
  10. "password": "{your-password}",
  11. "method": "aes-256-cfb", #none就填"none"
  12. "protocol": "origin",
  13. "protocol_param": "",
  14. "obfs": "plain",
  15. "obfs_param": "",
  16. "speed_limit_per_con": 0,
  17. "speed_limit_per_user": 0,
  18. "additional_ports" : {}, // only works under multi-user mode
  19. "additional_ports_only" : false, // only works under multi-user mode
  20. "timeout": 120,
  21. "udp_timeout": 60,
  22. "dns_ipv6": false,
  23. "connect_verbose_info": 0,
  24. "redirect": "",
  25. "fast_open": false
  26. }
  27. ssr start # 成功的话,将输出以下内容
  28. IPv6 not support
  29. started
  30. Testing Connection...
  31. local_port is 1080; if any exceptions orrured, please install jq
  32. connection information:
  33. {
  34. "ip": "103.225.11.201",
  35. "hostname": "103-225-11-201.layerdns.cloud",
  36. "city": "Central",
  37. "region": "Central and Western",
  38. "country": "HK",
  39. "loc": "22.2830,114.1585",
  40. "org": "AS133905 Layerstack Limited",
  41. "timezone": "Asia/Hong_Kong",
  42. "readme": "https://ipinfo.io/missingauth"
  43. }
  44. IP : 103.225.11.201
  45. 地址 : 中国 香港 ximbo.com
  46. 数据二 : 亚太地区
  47. 数据三 : 中国香港
  48. URL : http://www.cip.cc/103.225.11.201
  49. You may install proxychains4 and configure it properly to test net delay
  50. root@iZwz9e0l08off6jgpegc80Z:~/.local/share/shadowsocksr# git clone https://github.com/testerSunshine/12306.git
  51. Cloning into '12306'...
  52. remote: Enumerating objects: 3, done.
  53. remote: Counting objects: 100% (3/3), done.
  54. remote: Compressing objects: 100% (3/3), done.
  55. remote: Total 2727 (delta 0), reused 0 (delta 0), pack-reused 2724
  56. Receiving objects: 100% (2727/2727), 57.17 MiB | 3.80 MiB/s, done.
  57. Resolving deltas: 100% (1805/1805), done.
  58. Checking connectivity... done.

此时ssr就已经ok了,可以使用socks5代理。为了在命令行中方便的使用代理,还需要安装proxychains,它可以自动将当前命令的流量通过指定的端口代理。

安装proxychains

  1. # 安装proxychains
  2. sudo apt-get install proxychains
  3. # 配置proxychains.conf
  4. sudo vim /etc/proxychains.conf

将文件内容末尾的socks4 127.0.0.1 9050 前面加上井号# 注释,然后在下面加上socks5 127.0.0.1 1080 ,保存并退出。
完成,之后在执行需要科学上网的命令时都在前面加上proxychains。

使用代理

  • 通用代理

在所有需要代理的命令前加上proxychains即可。

  • http代理(需安装privoxy或polipo将http协议流量转由sock5代理)

    1. # 设置http 和 https 全局代理
    2. export http_proxy='http://localhost:8118'
    3. export https_proxy='http://localhost:8118'
    4. # 取消
    5. unset http_proxy
    6. unset https_proxy
  • 代理git(需安装ssr)

  1. git config --global http.proxy 'socks5://127.0.0.1:1080'
  2. git config --global https.proxy 'socks5://127.0.0.1:1080'
  3. # 取消
  4. git config --global --unset http.proxy
  5. git config --global --unset https.proxy

文件传输与同步

传文件

Linux scp命令

linux间的文件/文件夹的传输可以通过scp命令完成。该命令基于ssh,所以,如果你的终端和服务器都是linux系统,并且终端已经通过ssh登录了服务器,那么,就可以通过该命令进行文件传输了。

用法:

  1. 从本地复制文件到远程
    1. scp local_file remote_username@remote_ip:remote_folder
    2. 或者
    3. scp local_file remote_username@remote_ip:remote_file
    4. 或者
    5. scp local_file remote_ip:remote_folder
    6. 或者
    7. scp local_file remote_ip:remote_file
    :::tips
  • 第1,2个指定了用户名,命令执行后需要再输入密码,第1个仅指定了远程的目录,文件名字不变,第2个指定了文件名;
  • 第3,4个没有指定用户名,命令执行后需要输入用户名和密码,第3个仅指定了远程的目录,文件名字不变,第4个指定了文件名; :::
  1. 从本地复制文件夹到远程
    1. scp -r local_folder remote_username@remote_ip:remote_folder
    2. 或者
    3. scp -r local_folder remote_ip:remote_folder
    :::tips
  • 第1个指定了用户名,命令执行后需要再输入密码;
  • 第2个没有指定用户名,命令执行后需要输入用户名和密码; :::
  1. 从远程复制到本地

从远程复制到本地,只要将从本地复制到远程的命令的后2个参数调换顺序即可

  1. scp root@www.runoob.com:/home/root/others/music /home/space/music/1.mp3
  2. scp -r www.runoob.com:/home/root/others/ /home/space/music/

如果远程服务器防火墙为scp命令设置了指定的端口,我们需要使用-P参数来指定传输端口

  1. #scp 命令使用端口号 4588
  2. scp -P 4588 remote@www.runoob.com:/usr/local/sin.sh /home/administrator

:::info 如果想要用windows向linux传输文件,可以使用putty目录下的PSCP工具,为了更方便的使用,建议将该工具路径加入path中。首先打开cmd并cd到pscp.exe所在的目录,然后:pscp -r 目录 用户名@LinuxIP:目录。 :::

jupyter notebook

基本配置

通过jupyter notebook进行远程调参,只需以下几步:

  1. 生成配置文件
  1. jupyter notebook --generate-config
  2. # 生成了~/.jupyter/jupyter_notebook_config.py配置文件
  1. 修改配置文件
  1. vim ~/.jupyter/jupyter_notebook_config.py
  2. # 修改配置文件中一下内容,去掉注释后保存,配置文件默认都是注释掉的,如果找不到一下内容,
  3. # 那就直接在文件头输入保存即可。
  4. c.NotebookApp.ip='*' # 就是设置所有ip地址皆可访问
  5. #或者c.NotebookApp.ip='0.0.0.0'
  6. c.NotebookApp.password = u'sha:ce...' # 复制的那个密文key 替换等号后面的内容,注意,有u' c.NotebookApp.open_browser = False # 禁止自动打开浏览器
  7. c.NotebookApp.port =8888 # 指定一个可用端口,也可以是其他闲置的端口
  1. (可选)服务器端生成jupyter notebook的密码

    1. $ jupyter notebook password
    2. Enter password: ****
    3. Verify password: ****
    4. [NotebookPasswordApp] Wrote hashed password to /Users/you/.jupyter/jupyter_notebook_config.json
  2. 服务器端打开jupyter notebook

    1. jupyter notebook --no-browser --port=8889
  3. 本地开启端口转发

  • linux:

在本地通过ssh隧道来将服务器端的8889端口号映射到本地的某个端口(如1234)

  1. ssh -L 1234:localhost:8888 dlnlp@102.10.60.23
  • windows

通过putty建立端口转发,效果与上面的shell语句效果是一样的。
image.png

  1. 在终端浏览器中打开 http://localhost:1234 ,然后输入上面设置的密码。最后,选择下虚拟环境就可以开始愉快的debug了。
  2. (可选)指定jupyter notebook的虚拟环境

默认情况下jupyter notebook是运行在系统的默认环境下的,如果要让它运行在通过conda建立的环境中,我们可以进入那个环境安装nb_conda这个库: conda install nb_conda 。或者可以参考此处以不同环境建立多个内核。

jupyter绑定域名

参考:
jupyter 安装教程
Windows Server 下用 Nginx 配置 https 域名访问 Jupyter Notebook 服务
nginx制作和添加ssl证书

访问服务器的jupyter服务的最优雅的方式莫过于通过域名。不绑定域名的方式参考此处
在此之前首先完成以下工作:

  • 域名注册和解析
  • 服务器运行三个月以上(备案要求)
  • 备案
  • nginx(服务器应用)配置

此处着重最后一点,分为两步进行

nginx配置

安装nginx

  1. apt install nginx

nginx的默认配置文件是/etc/nginx/nginx.conf,然后通过#61、#62两个include语句导入网页配置。

  1. include /etc/nginx/conf.d/*.conf;
  2. include /etc/nginx/sites-enabled/*;

所以如果conf.d中有有效的网页配置文件,nginx将首先部署该配置,否则将部署sites-enabled中的页面。

这里建议将nginx.conf中的第一个include语句通过加#注释掉。
然后编辑sites-enabled中的页面。

sudo vim /etc/nginx/sites-enabled/default

然后可以将打开的配置文件中有效语句全部注释掉(vim快速注释)。
然后在最后粘贴以下内容:

server {
    listen 80;
    server_name eastzzp.top;
    # 将上面这个域名,替换为你的域名

    access_log /var/log/nginx/jupyter.access.log;
    error_log /var/log/nginx/jupyter.error.log;

    charset utf-8;

    location / {
        proxy_hide_header X-Powered-By;

        proxy_redirect off;
        proxy_pass http://localhost:8888;
        # 这是jupyter服务的默认端口,根据需要修改
        proxy_http_version 1.1;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_host;
    }
}

刷新nginx配置
需要注意的是,刷新后需要清楚浏览器缓存再打开页面。

sudo nginx -s reload

通过screen命令(ctrl+A+D)切换到jupyter服务虚拟桌面,然后开启jupyter服务,注意,如果不是以默认端口开启,需要修改上面的location->proxy_pass项,并再次刷新。

如果此时完成了备案,在本地的浏览器输入域名应当已经可以访问jupyter的服务了。 :::info nginx常用命令:

  • nginx -c /etc/nginx/….conf:自定义配置文件来覆盖默认配置
  • nginx -t:检查当前默认配置文件是否无误
  • sudo nginx -s reload:重启nginx服务 :::

设置ssl服务

添加ssl服务,使网站从http变为https。SSL 证书可以在阿里云、腾讯云免费申请。
这里以阿里云为例,选择免费套餐购买。购买后对购买到的证书绑定域名进行验证。完成后下载到服务器中。

把域名证书放入/etc/nginx/ssl文件夹下。

重新编辑/etc/nginx/sites-enabled/default,将之前的代码删除,粘贴一下内容:

windows服务器:

server {
        listen 80;
        server_name eastzzp.top;
        # 把所有 http 的访问强制重定向到 https 上
        return 301 https://$server_name$request_uri;
    }

server{
    listen 443 ssl http2;
    ssl on;
    server_name eastzzp.top;
    # 证书和密钥的位置
    ssl_certificate /etc/nginx/ssl/3037518_eastzzp.top.pem;
    ssl_certificate_key /etc/nginx/ssl/3037518_eastzzp.top.key;
    ssl_ciphers "EECDH CHACHA20:EECDH CHACHA20-draft:EECDH AES128:RSA AES128:EECDH AES256:RSA AES256:EECDH 3DES:RSA 3DES:!MD5";
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    # 为每一个域名设置单独的日志记录,比较方便查找
    access_log /var/log/nginx/jupyter.access.log;
    error_log /var/log/nginx/jupyter.error.log;
    # 使用websocket
    location / {
        proxy_pass            http://127.0.0.1:8888/;
        proxy_set_header      Host $host;
        proxy_http_version    1.1;
        proxy_set_header      Upgrade "websocket";
        proxy_set_header      Connection "Upgrade";
        proxy_read_timeout    86400;
    }
}

linux服务器:

server {
    listen 80;
    server_name eastzzp.top;
    #上面这个域名,替换为你的域名
    rewrite / https://$host$uri permanent;
    # http 重定向 https
    access_log /var/log/nginx/jupyter.access.log;
    error_log /var/log/nginx/jupyter.error.log;
    charset utf-8;
    root /var/www/jupyter;
}
server {
    listen 443;
    server_name eastzzp.top;
    #上面这个域名,替换为你的域名
    access_log /var/log/nginx/jupyter.access.log;
    error_log /var/log/nginx/jupyter.error.log;
    charset utf-8;
    ssl on;
    ssl_certificate /etc/nginx/ssl/3037518_eastzzp.top.pem;
    #替换为你的域名
    ssl_certificate_key /etc/nginx/ssl/3037518_eastzzp.top.key;
    #替换为你的域名
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_protocols TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES256;
    location / {
        proxy_hide_header X-Powered-By;
        proxy_redirect off;
        proxy_pass http://localhost:8888;
        proxy_http_version 1.1;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_host;
    }
}

然后重启nginx。

tensorboard

在服务器端指定端口打开tensorboard

tensorboard --logdir=log --port=6006

要在本地使用tensorboard,首先要在本地进行端口映射(操作同jupyter notebook)

ssh -L 16006:127.0.0.1:6006 usr@192.168.1.115

然后在本地浏览器中打开 localhost:16006 就可以访问到服务器上的tensorboard了。

pycharm

服务器常用操作

查询

查看CUDA和CUDNN版本

首先打开 ~/.bashrc 查看确定你当前环境调用的CUDA在什么位置。通常里面会有这三行:

PATH="$PATH:/usr/local/cuda-8.0/bin"
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/cuda-8.0/lib64/"
LIBRARY_PATH="$LIBRARY_PATH:/usr/local/cuda-8.0/lib64"

这三行说明当前shell环境调用的是 /usr/local/cuda-8.0/ 中的cuda,虽然文件夹给出了cuda的版本号,但如果不明确,我们可以通过以下命令查询:

# 打印cuda版本
cat /usr/local/cuda/version.txt
# 打印cudnn版本
cat /usr/local/cuda/include/cudnn.h | grep CUDNN_MAJOR -A 2

如果需要将cuda和cudnn切换为其他版本,只需要在 ~/.bashrc 中对应上面三行的cuda路径更换为其他版本cuda安装位置即可。

查看内存使用: free -m

image.png

Mem行(单位均为M):

  • total:内存总数
  • used:已使用内存数
  • free:空闲内存数
  • shared:当前废弃不用
  • buffers:缓存内存数(Buffer)
  • cached:缓存内舒数(Page)

(-/+ buffers/cache)行:

  • (-buffers/cache): 真正使用的内存数,指的是第一部分的 used - buffers - cached
  • (+buffers/cache): 可用的内存数,指的是第一部分的 free + buffers + cached

Swap行指交换分区。

实际上不要看free少就觉得内存不足了,buffers和cached都是可以在使用内存时拿来用的,应该以(-/+ buffers/cache)行的free和used来看。只要没发现swap的使用,就不用太担心,如果swap用了很多,那就要考虑增加物理内存了。

查看CPU使用: top

image.png

上方文字部分的红框为总的CPU占用百分率,下方的表格是每个进程的CPU占用率,在表格第一行可以看到红框中占用率超过了150%,这是因为服务器是多核CPU,而该进程使用了多核。

查看显卡使用情况: nvidia-smi

image.png

表格中会显示显卡的一些信息,第一行是版本信息,第二行是标题栏,第三行就是具体的显卡信息了,如果有多个显卡,会有多行,每一行的信息值对应标题栏对应位置的信息。

  • GPU:编号
  • Fan:风扇转速,在0到100%之间变动,这里是42%
  • Name:显卡名,这里是TITAN X
  • Temp:显卡温度,这里是69摄氏度
  • Perf:性能状态,从P0到P12,P0性能最大,P12最小
  • Persistence-M:持续模式的状态开关,该模式耗能大,但是启动新GPU应用时比较快,这里是off
  • Pwr:能耗
  • Bus-Id:涉及GPU总线的东西
  • Disp.A:表示GPU的显示是否初始化
  • Memory-Usage:现存使用率,这里已经快满了
  • GPU-Util:GPU利用率
  • Compute M.:计算模式

需要注意的一点是显存占用率和GPU占用率是两个不一样的东西,类似于内存和CPU,两个指标的占用率不一定是互相对应的。

在下面就是每个进程使用的GPU情况了。

常见问题处理

“Failed to create session”

通常是tf未能获得计算硬件,从而无法创建会话。我们可以通过CUDA_VISIBLE_DEVICES来指定可用的GPU。需要注意的是,指定了可用的GPU后,其他的GPU就不再可用。
首先,可以通过 nvidia-smi 获取当前可用的显卡信息,比如1、5号卡可用。

  1. 针对单个程序:
  • 在shell中追加:CUDA_VISIBLE_DEVICES=1,5 python main.py
  • 在代码中追加:import os; os.environ['CUDA_VISIBLE_DEVICES=1,5']
  1. 针对各个虚拟环境:
  • 修改~/.virtualenv/YOUR_VENV/bin/postactivate, 在末尾添加行export CUDA_VISIBLE_DEVICES="1,5"即可.
  1. 针对所有用户:
  • 同上修改~/.bashrc即可. :::info 如果你准备使用CPU,则可以通过CUDA_VISIBLE_DEVICES=’’隐藏所有GPU,TensorFlow将默认使用CPU进行计算。 :::

多任务管理

当我们通过ssh连接远程服务器后,在终端中新建的进程都属于当前终端的子进程,所以此时关闭窗口后,终端接收到HUP(hangup)信号后会关闭所有子进程。为了使程序可以继续运行,有以下方法:
关于这部分可以参考:Linux 技巧:让进程在后台运行更可靠的几种方法

screen

Linux screen命令

用法:

  • 通过-S新建session窗口

    screen -S yolo # 创建一个窗口,并且为这个窗口命名为yolo
    

    执行完后将自动跳入名为yolo的窗口

  • 断开窗口

通过快捷键Ctrl+A+D断开当前窗口连接返回会话界面,界面显示如下:

[detached from 28113.yolo]
user@ubuntu-Super-Server:~/code$

需要注意的是,断开连接仅是使窗口进入后台执行。

  • 查看已创建的窗口

    screen -ls #可以查看已创建的所有窗口
    # 结果显示如下
    user@ubuntu-Super-Server:~/code$ screen -ls
    There are screens on:
      28475.ssd    (2017年11月27日 20时07分41秒)    (Detached)
      28113.yolo    (2017年11月27日 19时57分26秒)    (Detached)
    
  • 重连窗口

    screen -r ssd #重新连接到yolo窗口,显示其运行过程
    
  • 关闭窗口

    $kill 28475 #终止28475.ssd窗口对应任务的运行,同时杀死该窗口
    

    :::info 若 screen -ls 里有 Attached sessions:
    screen -d [keyword] -> 强制 detach,以便「接手」过来 :::

byobu

tmux

强占式执行

在.bashrc中写入

alias python='run-one python'

该语句只允许运行一个python程序,后来的python程序在它执行完毕前是得不到执行的。

串行调参

通过python-fire这个工具,可以通过shell完成串行调参的需求。
通过服务器进行深度学习 - 图7