服务器配置
- ubuntu16.04服务器版
- anaconda
- cuda
-
安装
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/
登陆后可以直接通过内部工具链接服务器
即使忘记root密码,也可以通过网页登录后链接,然后sudo su获取root权限,接着passwd重置密码。
终端配置
linux/mac
linux/mac系统集成了ssh工具,所以可以在shell中直连服务器。
win10
如果是windows系统,那么我们需要一个ssh工具来完成ssh连接。xshell或者putty都可以胜任。
免密登陆
ssh同时还提供了公钥登录的方式。这点在上面的背景知识中已经介绍了。
具体的做法就是将你的公钥存储在服务器的ssh信任列表中中。
- 生成秘钥
# -P表示需要密码,-P ‘’表示空密码ssh-keygen -t rsa -P ''之后系统会提示输入生成的密钥文件的文件名,可以输入任意名称,比如id_rsa
- 找到自己的公钥,没有的话通过
ssh-keygen生成。然后通过scp命令传输公钥到服务器中。

- 在服务器中将刚刚的公钥添加到ssh信任列表。然后即可免密登陆了。
cat -n id_rsa.pub>> ~/.ssh/authorized_keys # -n参数代表在末尾添加,如果列表为空,可以不加cat ~/.ssh/authorized_keys # 显示列表中的公钥,当然,也可以用vim
:::info 如果还是无法免密登陆,有以下几个可能
- 服务器端的
.ssh和authorized_keys的权限不匹配。- 一般修改.ssh文件夹的权限就够了
chmod 700 /home/skyler/.ssh
- 如无必要不作修改
chmod 600 /home/skyler/.ssh/authorized_keys
- ssh配置文件未开启秘钥登陆
vi /etc/ssh/sshd_config
#RSAAuthentication yes#PubkeyAuthentication yes#AuthorizedKeysFile %h/.ssh/authorized_keys
取消以上代码的注释符,之后重启ssh服务: service ssh restart
- 如果是使用putty终端登陆服务器,需要在Connection->SSH->Auth中添加对应的私钥。
- 如果是阿里云的服务器,应当通过阿里云的控制台创建密钥对,以本地为windows为例:创建密钥对后在控制台重启服务器,然后通过puttygen将下载的私钥转化为ppk格式,最后在putty的
Auth中添加私钥。ok~ :::
服务器使用代理
注意,这里说的是让服务器使用代理客户端,而不是配置服务端。
参考博客:Ubuntu Server 18.04 LTS 使用Shadowsocks-ShadowsocksR访问互联网
安装git
apt install git
安装ssr
通过一键脚本安装ssr
wget https://github.com/the0demiurge/CharlesScripts/raw/master/charles/bin/ssr
这个脚本算是写的比较完善了,里面封装了 SSR 的安装、配置、启动、关闭等功能。
为了方便操作,我们将脚本放进/usr/local/bin中(里面的程序将自动加入path中,可以在任意位置执行)
sudo mv ssr /usr/local/binsudo chmod 766 /usr/local/bin/ssr
然后任意位置执行
ssr install #自动安装到 $HOME/.local/share/shadowsocksrssr help # 获取帮助信息ssr config # 编辑配置信息,如下{"server": "{your-server}","server_ipv6": "::","server_port": 12345,"local_address": "127.0.0.1","local_port": 1080,"password": "{your-password}","method": "aes-256-cfb", #none就填"none""protocol": "origin","protocol_param": "","obfs": "plain","obfs_param": "","speed_limit_per_con": 0,"speed_limit_per_user": 0,"additional_ports" : {}, // only works under multi-user mode"additional_ports_only" : false, // only works under multi-user mode"timeout": 120,"udp_timeout": 60,"dns_ipv6": false,"connect_verbose_info": 0,"redirect": "","fast_open": false}ssr start # 成功的话,将输出以下内容IPv6 not supportstartedTesting Connection...local_port is 1080; if any exceptions orrured, please install jqconnection information:{"ip": "103.225.11.201","hostname": "103-225-11-201.layerdns.cloud","city": "Central","region": "Central and Western","country": "HK","loc": "22.2830,114.1585","org": "AS133905 Layerstack Limited","timezone": "Asia/Hong_Kong","readme": "https://ipinfo.io/missingauth"}IP : 103.225.11.201地址 : 中国 香港 ximbo.com数据二 : 亚太地区数据三 : 中国香港URL : http://www.cip.cc/103.225.11.201You may install proxychains4 and configure it properly to test net delayroot@iZwz9e0l08off6jgpegc80Z:~/.local/share/shadowsocksr# git clone https://github.com/testerSunshine/12306.gitCloning into '12306'...remote: Enumerating objects: 3, done.remote: Counting objects: 100% (3/3), done.remote: Compressing objects: 100% (3/3), done.remote: Total 2727 (delta 0), reused 0 (delta 0), pack-reused 2724Receiving objects: 100% (2727/2727), 57.17 MiB | 3.80 MiB/s, done.Resolving deltas: 100% (1805/1805), done.Checking connectivity... done.
此时ssr就已经ok了,可以使用socks5代理。为了在命令行中方便的使用代理,还需要安装proxychains,它可以自动将当前命令的流量通过指定的端口代理。
安装proxychains
# 安装proxychainssudo apt-get install proxychains# 配置proxychains.confsudo vim /etc/proxychains.conf
将文件内容末尾的socks4 127.0.0.1 9050 前面加上井号# 注释,然后在下面加上socks5 127.0.0.1 1080 ,保存并退出。
完成,之后在执行需要科学上网的命令时都在前面加上proxychains。
使用代理
- 通用代理
在所有需要代理的命令前加上proxychains即可。
http代理(需安装privoxy或polipo将http协议流量转由sock5代理)
# 设置http 和 https 全局代理export http_proxy='http://localhost:8118'export https_proxy='http://localhost:8118'# 取消unset http_proxyunset https_proxy
代理git(需安装ssr)
git config --global http.proxy 'socks5://127.0.0.1:1080'git config --global https.proxy 'socks5://127.0.0.1:1080'# 取消git config --global --unset http.proxygit config --global --unset https.proxy
文件传输与同步
传文件
linux间的文件/文件夹的传输可以通过scp命令完成。该命令基于ssh,所以,如果你的终端和服务器都是linux系统,并且终端已经通过ssh登录了服务器,那么,就可以通过该命令进行文件传输了。
用法:
- 从本地复制文件到远程
:::tipsscp local_file remote_username@remote_ip:remote_folder或者scp local_file remote_username@remote_ip:remote_file或者scp local_file remote_ip:remote_folder或者scp local_file remote_ip:remote_file
- 第1,2个指定了用户名,命令执行后需要再输入密码,第1个仅指定了远程的目录,文件名字不变,第2个指定了文件名;
- 第3,4个没有指定用户名,命令执行后需要输入用户名和密码,第3个仅指定了远程的目录,文件名字不变,第4个指定了文件名; :::
- 从本地复制文件夹到远程
:::tipsscp -r local_folder remote_username@remote_ip:remote_folder或者scp -r local_folder remote_ip:remote_folder
- 第1个指定了用户名,命令执行后需要再输入密码;
- 第2个没有指定用户名,命令执行后需要输入用户名和密码; :::
- 从远程复制到本地
从远程复制到本地,只要将从本地复制到远程的命令的后2个参数调换顺序即可
scp root@www.runoob.com:/home/root/others/music /home/space/music/1.mp3scp -r www.runoob.com:/home/root/others/ /home/space/music/
如果远程服务器防火墙为scp命令设置了指定的端口,我们需要使用-P参数来指定传输端口
#scp 命令使用端口号 4588scp -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进行远程调参,只需以下几步:
- 生成配置文件
jupyter notebook --generate-config# 生成了~/.jupyter/jupyter_notebook_config.py配置文件
- 修改配置文件
vim ~/.jupyter/jupyter_notebook_config.py# 修改配置文件中一下内容,去掉注释后保存,配置文件默认都是注释掉的,如果找不到一下内容,# 那就直接在文件头输入保存即可。c.NotebookApp.ip='*' # 就是设置所有ip地址皆可访问#或者c.NotebookApp.ip='0.0.0.0'c.NotebookApp.password = u'sha:ce...' # 复制的那个密文key 替换等号后面的内容,注意,有u' c.NotebookApp.open_browser = False # 禁止自动打开浏览器c.NotebookApp.port =8888 # 指定一个可用端口,也可以是其他闲置的端口
(可选)服务器端生成jupyter notebook的密码
$ jupyter notebook passwordEnter password: ****Verify password: ****[NotebookPasswordApp] Wrote hashed password to /Users/you/.jupyter/jupyter_notebook_config.json
服务器端打开jupyter notebook
jupyter notebook --no-browser --port=8889
- linux:
在本地通过ssh隧道来将服务器端的8889端口号映射到本地的某个端口(如1234)
ssh -L 1234:localhost:8888 dlnlp@102.10.60.23
- windows
通过putty建立端口转发,效果与上面的shell语句效果是一样的。
- 在终端浏览器中打开
http://localhost:1234,然后输入上面设置的密码。最后,选择下虚拟环境就可以开始愉快的debug了。 - (可选)指定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
apt install nginx
nginx的默认配置文件是/etc/nginx/nginx.conf,然后通过#61、#62两个include语句导入网页配置。
include /etc/nginx/conf.d/*.conf;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;
}
}
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

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
上方文字部分的红框为总的CPU占用百分率,下方的表格是每个进程的CPU占用率,在表格第一行可以看到红框中占用率超过了150%,这是因为服务器是多核CPU,而该进程使用了多核。
查看显卡使用情况: nvidia-smi

表格中会显示显卡的一些信息,第一行是版本信息,第二行是标题栏,第三行就是具体的显卡信息了,如果有多个显卡,会有多行,每一行的信息值对应标题栏对应位置的信息。
- 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号卡可用。
- 针对单个程序:
- 在shell中追加:
CUDA_VISIBLE_DEVICES=1,5 python main.py - 在代码中追加:
import os; os.environ['CUDA_VISIBLE_DEVICES=1,5']
- 针对各个虚拟环境:
- 修改
~/.virtualenv/YOUR_VENV/bin/postactivate, 在末尾添加行export CUDA_VISIBLE_DEVICES="1,5"即可.
- 针对所有用户:
- 同上修改
~/.bashrc即可. :::info 如果你准备使用CPU,则可以通过CUDA_VISIBLE_DEVICES=’’隐藏所有GPU,TensorFlow将默认使用CPU进行计算。 :::
多任务管理
当我们通过ssh连接远程服务器后,在终端中新建的进程都属于当前终端的子进程,所以此时关闭窗口后,终端接收到HUP(hangup)信号后会关闭所有子进程。为了使程序可以继续运行,有以下方法:
关于这部分可以参考: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完成串行调参的需求。
