首页 文章 精选 留言 我的

精选列表

搜索[搭建],共10000篇文章
优秀的个人博客,低调大师

如何搭建大规模机器学习平台?以阿里和蚂蚁的多个实际场景为例

近年来,随着“大”数据及“大”模型的出现,学术界和工业界对分布式机器学习算法引起了广泛关注。针对这一刚需,本论文设计了一个独一无二的分布式平台——鲲鹏。它无缝的结合了分布式系统及并行优化算法,解决了大规模机器学习算法带来的一系列问题。鲲鹏不仅囊括了数据/模型并行、负载平衡、模型同步、稀疏表示、工业容错等特性,而且还提供了封闭好的、宜于调用的API供普通的机器学习者开发分布式算法,降低使用成本并提升效率。 本论文的实验在十亿级别的样本和特征数据上进行,结果表示,鲲鹏这一设计使得一系列算法的性能都得到了极大的提升,包括FTRL,Sparse-LR,以及MART。此外,鲲鹏在阿里巴巴双11狂欢购物节及蚂蚁金服的交易风险检测中体现出了其巨大的应用价值。 研究背景 现在是个大数据的时代,各个平台的数据量都与时俱进。举例而言,国外的Twitter每

优秀的个人博客,低调大师

rhel6上搭建lnmp架构以及遇到的一些错误并排除方法

先装好rhel6.5 配置好实验环境 关掉NetworkManager,并停止掉开机自启动 [root@duwensql~]#serviceNetworkManagerstop [root@duwensql~]#chkconfig--listNetworkManager [root@duwensql~]#chkconfigNetworkManageroff 关掉iptables [root@duwensql~]#iptables-F [root@duwensql~]#serviceiptablessave iptables£o·àe1ò±£′μ/etc/sysconfig/iptables£o[è·¨] [root@duwensql~]#chkconfigiptablesoff 关掉selinux [root@duwensql~]#getenforce Enforcing [root@duwensql~]#setenforce usage:setenforce[Enforcing|Permissive|1|0] [root@duwensql~]#setenforce0 [root@duwensql~]# [root@duwensql~]#vim/etc/selinux/config 打开这个档案以后你可以看到如下的内容,把SELINUX的值改成disabled就好 #ThisfilecontrolsthestateofSELinuxonthesystem. #SELINUX=cantakeoneofthesethreevalues: #enforcing-SELinuxsecuritypolicyisenforced. #permissive-SELinuxprintswarningsinsteadofenforcing. #disabled-NoSELinuxpolicyisloaded. SELINUX=disabled #SELINUXTYPE=cantakeoneofthesetwovalues: #targeted-Targetedprocessesareprotected, #mls-MultiLevelSecurityprotection. SELINUXTYPE=targeted 修改主机名映射,可以不改,但是为了方便还是改下吧 [root@duwensql~]#cat/etc/hosts 127.0.0.1localhostlocalhost.localdomainlocalhost4localhost4.localdomain4 ::1localhostlocalhost.localdomainlocalhost6localhost6.localdomain6 [root@duwensql~]#echo"192.168.20.253duwensql.cnMySQL">>/etc/hosts [root@duwensql~]#cat/etc/hosts 127.0.0.1localhostlocalhost.localdomainlocalhost4localhost4.localdomain4 ::1localhostlocalhost.localdomainlocalhost6localhost6.localdomain6 192.168.20.253duwensql.cnMySQL [root@duwensql~]# 修改主机名,就是编辑下面的这个档案,这里只贴上修改后的内容 [root@duwensql~]#cat/etc/sysconfig/network NETWORKING=yes HOSTNAME=duwensql.cn GATEWAY=192.168.20.2 NTPSERVERARGS=iburst [root@duwensql~]# 配置本地yum源 [root@duwensql~]# [root@duwensql~]#mount/dev/sr0/mnt/ mount:blockdevice/dev/sr0iswrite-protected,mountingread-only [root@duwensql~]#df-h|tail-1 /dev/sr03.6G3.6G0100%/mnt [root@duwensql~]#echo"/dev/sr0/mnt/iso9660defaults00">>/etc/fstab [root@duwensql~]#rm-rf/etc/yum.repos.d/* [root@duwensql~]#cat>/etc/yum.repos.d/rhel6.repo<<EOF >[rhel6-source] >name=rhel6-source >baseurl=file:///mnt >enabled=1 >gpgcheck=0 >EOF [root@duwensql~]#yumcleanall Loadedplugins:product-id,refresh-packagekit,security,subscription-manager ThissystemisnotregisteredtoRedHatSubscriptionManagement.Youcanusesubscription-managertoregister. Cleaningrepos:rhel6-source CleaningupEverything [root@duwensql~]#yumlist 检测依赖环境,包括gcc,gcc-c++,autoconf,automake,zlib ,zlib-devel, openssl ,openssl-devel ,pcre-devel, [root@duwensql~]# [root@duwensql~]#yuminstall-ygccgcc-c++autoconfautomake [root@duwensql~]#yuminstall-yzlibzlib-developensslopenssl-develpcre-devel 为了方便从xshell上传软件包,这里安装一个工具 [root@duwensql~]#rpm/mnt/Packages/lrzsz-0.12.20-27.1.el6.x86_64.rpm-ih warning:/mnt/Packages/lrzsz-0.12.20-27.1.el6.x86_64.rpm:HeaderV3RSA/SHA256Signature,keyIDfd431d51:NOKEY ###########################################[100%] ###########################################[100%] [root@duwensql~]# //上传软件包:nginx-1.6.0.tar.gzmysql-5.5.30.tar.gz php-5.4.14.tar.bz2 [root@duwensql~]#rz zwaitingtoreceive.**B0100000023be50 [root@duwensql~]#ls anaconda-ks.cfginstall.log.syslognginx-1.6.0.tar.gz公共的视频文档音乐 install.logmysql-5.5.30.tar.gzphp-5.4.14.tar.bz2模板图片下载桌面 正式开始安装MySQL了 解压到指定目录/usr/local/src/ [root@duwensql~]# [root@duwensql~]#tar-zxfmysql-5.5.30.tar.gz-C/usr/local/src/ 建一个mysql用户,这里把这个用户显示出来 [root@duwensql~]#tail-1/etc/passwd mysql:x:500:500::/home/mysql:/sbin/nologin [root@duwensql~]# //安装cmake [root@duwensql~]#yuminstall-ycmake 建立mysql的目录 [root@duwensql/]#mkdir/server [root@duwensql~]#cd/usr/local/src/mysql-5.5.30/ [root@duwensqlmysql-5.5.30]#cmake-DCMAKE_INSTALL_PREFIX=/server/mysql-5.5-DMYSQL_UNIX_ADDR=/tmp/mysql.sock-DDEFAULT_CHARSET=utf8-DDEFAULT_COLLATION=utf8_general_ci-DWITH_EXTRA_CHARSERS=all-DWITH_MYISAM_STORAGE_ENGINE=1-DWITH_INNOBASE_STORAGE_ENGINE=1-DWITH_MEMORY_STORAGE_ENGINE=1-DWITH_READLINT=1-DENABLED_LOCAL_INFILE=1-DMYSQL_DATADIR=/server/mysql/data-DMYSQL_USER=mysql //报错啦啦啦啦 CMakeErroratcmake/readline.cmake:83(MESSAGE): Curseslibrarynotfound.Pleaseinstallappropriatepackage, removeCMakeCache.txtandreruncmake.OnDebian/Ubuntu,packagenameislibncurses5-dev,onRedhatandderivatesitisncurses-devel. CallStack(mostrecentcallfirst): cmake/readline.cmake:127(FIND_CURSES) cmake/readline.cmake:217(MYSQL_USE_BUNDLED_LIBEDIT) CMakeLists.txt:269(MYSQL_CHECK_READLINE) --Configuringincomplete,errorsoccurred! //这个错误就是ncurses这个依赖没有装,yum安装一下 [root@duwensqlncurses-5.9]#yum-yinstallncurses-devel //装了那个ncurses依赖,还是报错,就只好把这个CMakeCache.txt找出来干掉了 [root@duwensqlmysql-5.5.30]#find/-nameCMakeCache.txt /usr/local/src/mysql-5.5.30/CMakeCache.txt [root@duwensqlmysql-5.5.30]#rm-rf/usr/local/src/mysql-5.5.30/CMakeCache.txt //OK,现在重新cmake //呐开心不,没有报错了呢!!! 现在make &&make install,过程就不写了 配置运行环境 [root@duwensqlmysql-5.5.30]#cd/server/ [root@duwensqlserver]#ls mysql-5.5 [root@duwensqlserver]#chown-Rmysql:mysql/server/mysql-5.5/ 复制mysql配置文件 [root@duwensqlserver]#cd/etc/ [root@duwensqletc]#llmy.cnf -rw-r--r--.1rootroot2518月92013my.cnf [root@duwensqletc]#mv./my.cnf./my.cnf.back [root@duwensqletc]#cp/usr/local/src/mysql-5.5.30/support-files/my-large.cnf/etc/my.cnf [root@duwensqletc]# 这个步骤是加入开机启动项 [root@duwensqlinit.d]#cp/usr/local/src/mysql-5.5.30/support-files/mysql.server/etc/init.d/mysqld5.5 [root@duwensqlinit.d]#chmod+x./mysqld5.5 [root@duwensqlinit.d]#pwd /etc/init.d [root@duwensqlinit.d]# //这里要改下,大概在第70行 [root@duwensqlinit.d]#vim/etc/init.d/mysqld5.5 [root@duwensqlinit.d]#head-71/etc/init.d/mysqld5.5|tail-7 then basedir=/server/mysql-5.5 bindir=/server/mysql-5.5/bin iftest-z"$datadir" then datadir=/server/mysql-5.5/data fi [root@duwensqlinit.d]# //加入开机启动项 [root@duwensqlinit.d]#chkconfigmysqld5.5on [root@duwensqlinit.d]#chkconfig--listmysqld5.5 mysqld5.50:关闭1:关闭2:启用3:启用4:启用5:启用6:关闭 [root@duwensqlinit.d]# 初始化mysql [root@duwensqlinit.d]#cd/usr/local/src/mysql-5.5.30/scripts/ [root@duwensqlscripts]#chmod+xmysql_install_db [root@duwensqlscripts]#./mysql_install_db--defaults-file=/etc/my.cnf--basedir=/server/mysql-5.5--datadir=/server/mysql-5.5/data--user=mysql InstallingMySQLsystemtables... OK Fillinghelptables... OK Tostartmysqldatboottimeyouhavetocopy support-files/mysql.servertotherightplaceforyoursystem PLEASEREMEMBERTOSETAPASSWORDFORTHEMySQLrootUSER! Todoso,starttheserver,thenissuethefollowingcommands: /server/mysql-5.5/bin/mysqladmin-urootpassword'new-password' /server/mysql-5.5/bin/mysqladmin-uroot-hduwensqlpassword'new-password' Alternativelyyoucanrun: /server/mysql-5.5/bin/mysql_secure_installation whichwillalsogiveyoutheoptionofremovingthetest databasesandanonymoususercreatedbydefault.Thisis stronglyrecommendedforproductionservers. Seethemanualformoreinstructions. YoucanstarttheMySQLdaemonwith: cd/server/mysql-5.5;/server/mysql-5.5/bin/mysqld_safe& YoucantesttheMySQLdaemonwithmysql-test-run.pl cd/server/mysql-5.5/mysql-test;perlmysql-test-run.pl Pleasereportanyproblemswiththe/server/mysql-5.5/scripts/mysqlbugscript! [root@duwensqlscripts]# 开启mysql [root@duwensqlscripts]#/etc/init.d/mysqld5.5start StartingMySQL...[确定] [root@duwensqlscripts]# 测试MySQL //我这里最开始在家目录输入mysql显示没有命令,是因为没有加入环境变量的缘故啦,这里就不写出来了,直接到绝对路径去测试 root@duwensqlmysql-test]#cd/server [root@duwensqlserver]#ls mysql-5.5 [root@duwensqlserver]#cdmysql-5.5/ [root@duwensqlmysql-5.5]#ls binCOPYINGdatadocsincludeINSTALL-BINARYlibmanmysql-testREADMEscriptssharesql-benchsupport-files [root@duwensqlmysql-5.5]#cdbin/ [root@duwensqlbin]#./mysql WelcometotheMySQLmonitor.Commandsendwith;or\g. YourMySQLconnectionidis1 Serverversion:5.5.30-logSourcedistribution Copyright(c)2000,2013,Oracleand/oritsaffiliates.Allrightsreserved. OracleisaregisteredtrademarkofOracleCorporationand/orits affiliates.Othernamesmaybetrademarksoftheirrespective owners. Type'help;'or'\h'forhelp.Type'\c'toclearthecurrentinputstatement. mysql>showdatabases; +--------------------+ |Database| +--------------------+ |information_schema| |mysql| |performance_schema| |test| +--------------------+ 4rowsinset(0.04sec) mysql> ctrl + c 退出 给他加个环境变量吧 [root@duwensql~]#echo$PATH /usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin [root@duwensql~]#PATH="$PATH":/server/mysql-5.5/bin/ 设置mysql的root账户密码,并测试登陆 [root@duwensql~]#mysqladmin-urootpassword'123456' [root@duwensql~]#mysql-uroot-p123456 WelcometotheMySQLmonitor.Commandsendwith;or\g. YourMySQLconnectionidis4 Serverversion:5.5.30-logSourcedistribution Copyright(c)2000,2013,Oracleand/oritsaffiliates.Allrightsreserved. OracleisaregisteredtrademarkofOracleCorporationand/orits affiliates.Othernamesmaybetrademarksoftheirrespective owners. Type'help;'or'\h'forhelp.Type'\c'toclearthecurrentinputstatement. mysql> ctrl + c 退出 MySQL安装完了 来安装nginx吧 解压 [root@duwensql~]#tar-zxfnginx-1.6.0.tar.gz 编译 [root@duwensqlnginx-1.6.0]#./configure--prefix=server/nginx-1.6.0--user=nginx--group=nginx--with-http_dav_module--with-http_stub_status_module--with-http_addition_module--with-http_sub_module--with-http_flv_module--with-http_mp4_module 结果太多就不写了,放一个图 make&&make install [root@duwensqlnginx-1.6.0]#make-j4&&makeinstall 开始配置 [root@duwensqlnginx-1.2.8]#pwd /server/nginx-1.2.8 [root@duwensqlnginx-1.2.8]#vimconf/nginx.conf 第二行加 usernginxnginx; 然后加下面的内容,括号{前面有空格 location~\.php${ roothtml; fastcgi_pass127.0.0.1:9000; fastcgi_indexindex.php; fastcgi_paramSCRIPT_FILENAME/server/nginx-1.2.8/html$fastcgi_script_name; includefastcgi_params; } 大概的位置如下图 启动服务 [root@duwensqlnginx-1.2.8]#/server/nginx-1.2.8/sbin/nginx 把服务加入开机启动 [root@duwensqlnginx-1.2.8]#echo'/server/nginx-1.2.8/sbin/nginx&'>>/etc/rc.local [root@duwensqlnginx-1.2.8]# 测试下 测试配置文件和重新加载配置文件 [root@duwensqlnginx-1.2.8]#/server/nginx-1.2.8/sbin/nginx-t nginx:theconfigurationfile/server/nginx-1.2.8/conf/nginx.confsyntaxisok nginx:configurationfile/server/nginx-1.2.8/conf/nginx.conftestissuccessful [root@duwensqlnginx-1.2.8]#/server/nginx-1.2.8/sbin/nginx-sreload 来安装PHP 给PHP添加扩展模块:libmcrypt-2.5.8.tar.gz 1、 让 PHP 编译支持这个功能 2、 生成扩展模块 3、 --with-mcrypt=/usr/local/ 安装libmcrypt库 [root@duwensql~]#tar-zxflibmcrypt-2.5.8.tar.gz [root@duwensql~]#cdlibmcrypt-2.5.8 [root@duwensqllibmcrypt-2.5.8]#./configure--prefix=/usr/local/ [root@duwensqllibmcrypt-2.5.8]#echo$? 0 [root@duwensqllibmcrypt-2.5.8]#make-j4&&makeinstall 加个环境 [root@duwensqllibmcrypt-2.5.8]#yum-yinstallphp-pear 解压以及编译 //在这一步出了好多好多错误,始料不及啊,本文把错误和解决贴上,如果还是不明白的话可以直接搜索错误,这里就不写了 [root@duwensql~]#tarjxfphp-5.4.14.tar.bz2-C/usr/local/src/ [root@duwensql~]#cd/usr/local/src/php-5.4.14/ [root@duwensqlphp-5.4.14]#./configure--prefix=/server/php-5.4-nginx--with-config-file-path=/server/php-5.4-nginx--with-mysql=/server-5.5/--with-mysqli=/server/mysql-5.5/bin/mysql_config--with-iconv-dir--with-freetype-dir--with-jpeg-dir--with-png-dir--with-zlib--with-libxml-dir=/usr--enable-xml--disable-rpath--enable-bcmath--enable-shmop--enable-sysvsem--enable-inline-optimization--with-curl--with-curlwrappers--enable-mbregex--enable-fpm--enable-mbstring--with-gd--enable-gd-native-ttf--with-openssl--with-mhash--enable-pcntl--enable-sockets--with-xmlrpc--enable-zip--enable-soap--with-mcrypt=/usr/local/ 报错1 ####### configure:error:xml2-confignotfound.Pleasecheckyourlibxml2installation. [root@duwensqlphp-5.4.14]# 解决1 [root@duwensqlphp-5.4.14]#yum-yinstalllibxml2* 重新编译 [root@duwensqlphp-5.4.14]#./configure--prefix=/server/php-5.4-nginx--with-config-file-path=/server/php-5.4-nginx--with-mysql=/server/mysql-5.5/--with-mysqli=/server/mysql-5.5/bin/mysql_config--with-iconv-dir--with-freetype-dir--with-jpeg-dir--with-png-dir--with-zlib--with-libxml-dir=/usr--enable-xml--disable-rpath--enable-bcmath--enable-shmop--enable-sysvsem--enable-inline-optimization--with-curl--with-curlwrappers--enable-mbregex--enable-fpm--enable-mbstring--with-gd--enable-gd-native-ttf--with-openssl--with-mhash--enable-pcntl--enable-sockets--with-xmlrpc--enable-zip--enable-soap--with-mcrypt=/usr/local/ 报错2 checkingifweshouldusecURLforurlstreams...yes checkingforcURLindefaultpath...notfound configure:error:Pleasereinstallthelibcurldistribution- easy.hshouldbein<curl-dir>/include/curl/ [root@duwensqlphp-5.4.14]# 解决2: [root@duwensqlphp-5.4.14]#yum-yinstallcurl-devel 重新编译 [root@duwensqlphp-5.4.14]#./configure--prefix=/server/php-5.4-nginx--with-config-file-path=/server/php-5.4-nginx--with-mysql=/server/mysql-5.5/--with-mysqli=/server/mysql-5.5/bin/mysql_config--with-iconv-dir--with-freetype-dir--with-jpeg-dir--with-png-dir--with-zlib--with-libxml-dir=/usr--enable-xml--disable-rpath--enable-bcmath--enable-shmop--enable-sysvsem--enable-inline-optimization--with-curl--with-curlwrappers--enable-mbregex--enable-fpm--enable-mbstring--with-gd--enable-gd-native-ttf--with-openssl--with-mhash--enable-pcntl--enable-sockets--with-xmlrpc--enable-zip--enable-soap--with-mcrypt=/usr/local/ 报错3 checkingwhethertoenableJIS-mappedJapanesefontsupportinGD...no checkingforfabsf...yes checkingforfloorf...yes configure:error:jpeglib.hnotfound 解决3:*不要丢了 [root@duwensqlphp-5.4.14]#yum-yinstalllibjpeg* 再次编译 [root@duwensqlphp-5.4.14]./configure--prefix=/server/php-5.4-nginx--with-config-file-path=/server/php-5.4-nginx--with-mysql=/server/mysql-5.5/--with-mysqli=/server/mysql-5.5/bin/mysql_config--with-iconv-dir--with-freetype-dir--with-jpeg-dir--with-png-dir--with-zlib--with-libxml-dir=/usr--enable-xml--disable-rpath--enable-bcmath--enable-shmop--enable-sysvsem--enable-inline-optimization--with-curl--with-curlwrappers--enable-mbregex--enable-fpm--enable-mbstring--with-gd--enable-gd-native-ttf--with-openssl--with-mhash--enable-pcntl--enable-sockets--with-xmlrpc--enable-zip--enable-soap--with-mcrypt=/usr/local/ 报错4: checkingforjpeg_read_headerin-ljpeg...yes Ifconfigurefailstry--with-vpx-dir=<DIR> configure:error:png.hnotfound. [root@duwensqlphp-5.4.14]# 解决4:*不要丢了 [root@duwensqlphp-5.4.14]#yum-yinstalllibpng* 再次编译 [root@duwensqlphp-5.4.14]#./configure--prefix=/server/php-5.4-nginx--with-config-file-path=/server/php-5.4-nginx--with-mysql=/server/mysql-5.5/--with-mysqli=/server/mysql-5.5/bin/mysql_config--with-iconv-dir--with-freetype-dir--with-jpeg-dir--with-png-dir--with-zlib--with-libxml-dir=/usr--enable-xml--disable-rpath--enable-bcmath--enable-shmop--enable-sysvsem--enable-inline-optimization--with-curl--with-curlwrappers--enable-mbregex--enable-fpm--enable-mbstring--with-gd--enable-gd-native-ttf--with-openssl--with-mhash--enable-pcntl--enable-sockets--with-xmlrpc--enable-zip--enable-soap--with-mcrypt=/usr/local/ 报错5: configure:error:freetype.hnotfound. 解决5:*不要丢掉了 [root@duwensqlphp-5.4.14]#yum-yinstallfreetype* 再次编译 [root@duwensqlphp-5.4.14]#./configure--prefix=/server/php-5.4-nginx--with-config-file-path=/server/php-5.4-nginx--with-mysql=/server/mysql-5.5/--with-mysqli=/server/mysql-5.5/bin/mysql_config--with-iconv-dir--with-freetype-dir--with-jpeg-dir--with-png-dir--with-zlib--with-libxml-dir=/usr--enable-xml--disable-rpath--enable-bcmath--enable-shmop--enable-sysvsem--enable-inline-optimization--with-curl--with-curlwrappers--enable-mbregex--enable-fpm--enable-mbstring--with-gd--enable-gd-native-ttf--with-openssl--with-mhash--enable-pcntl--enable-sockets--with-xmlrpc--enable-zip--enable-soap--with-mcrypt=/usr/local/ 报错6: checkingforspecifiedlocationoftheMySQLUNIXsocket...no configure:error:CannotfindMySQLheaderfilesunder/server-5.5/. NotethattheMySQLclientlibraryisnotbundledanymore! 这个应该是指定路径错误,改下 再次编译 [root@duwensqlphp-5.4.14]#./configure--prefix=/server/php-5.4-nginx--with-config-file-path=/server/php-5.4-nginx--with-mysql=/server/mysql-5.5/--with-mysqli=/server/mysql-5.5/bin/mysql_config--with-iconv-dir--with-freetype-dir--with-jpeg-dir--with-png-dir--with-zlib--with-libxml-dir=/usr--enable-xml--disable-rpath--enable-bcmath--enable-shmop--enable-sysvsem--enable-inline-optimization--with-curl--with-curlwrappers--enable-mbregex--enable-fpm--enable-mbstring--with-gd--enable-gd-native-ttf--with-openssl--with-mhash--enable-pcntl--enable-sockets--with-xmlrpc--enable-zip--enable-soap--with-mcrypt=/usr/local/ 报错7: configure:error:wrongmysqllibraryversionorlibnotfound.Checkconfig.logformoreinformation. 解决7: “=/server/mysql-5.5/bin/mysql_config”删掉试试 改好以后的执行: [root@duwensqlphp-5.4.14]#./configure--prefix=/server/php-5.4-nginx--with-config-file-path=/server/php-5.4-nginx--with-mysql=/server/mysql-5.5/--with-mysqli--with-iconv-dir--with-freetype-dir--with-jpeg-dir--with-png-dir--with-zlib--with-libxml-dir=/usr--enable-xml--disable-rpath--enable-bcmath--enable-shmop--enable-sysvsem--enable-inline-optimization--with-curl--with-curlwrappers--enable-mbregex--enable-fpm--enable-mbstring--with-gd--enable-gd-native-ttf--with-openssl--with-mhash--enable-pcntl--enable-sockets--with-xmlrpc--enable-zip--enable-soap--with-mcrypt=/usr/local/ 历经千辛万苦啊 这里贴上一些参数的意思 --with-iconv-dir #字符集转换 需要的扩展模块 –without-iconv 关闭 iconv 函数,种字符集间的转换 –with-freetype-dir 打开对 freetype 字体库的支持 –with-jpeg-dir 打开对 jpeg 图片的支持 –with-png-dir 打开对 png 图片的支持 –with-libxml-dir 打开 libxml2 库的支持 –disable-rpath 关闭额外的运行库文件 –enable-bcmath 打开图片大小调整,用到 zabbix 监控的时候用到了这个模块 下面 是make && make install [root@duwensqlphp-5.4.14]#make-j4&&makeinstall 生成配置文件 [root@duwensql~]#cp/usr/local/src/php-5.4.14/php.ini-production/server/php-5.4-nginx/php.ini 生成php-fpm配置文件 [root@duwensql~]#cp/server/php-5.4-nginx/etc/php-fpm.conf.default/server/php-5.4-nginx/etc/php-fpm.conf 生成php-fpm启动脚本 [root@duwensql~]#cp/usr/local/src/php-5.4.14/sapi/fpm/init.d.php-fpm/etc/init.d/php-fpm [root@duwensql~]#chmod+x/etc/init.d/php-fpm [root@duwensql~]#/etc/init.d/php-fpmstart Startingphp-fpmdone [root@duwensql~]#netstat-anptu|grep9000 tcp00127.0.0.1:90000.0.0.0:*LISTEN76616/php-fpm [root@duwensql~]# 测试php [root@duwensql~]#vim/server/nginx-1.2.8/html/a.php [root@duwensql~]#cat/server/nginx-1.2.8/html/a.php <?php phpinfo(); ?> [root@duwensql~]# 效果图如下 The End!

优秀的个人博客,低调大师

如何在双十一给自己送个“陪聊女友”——基于飞桨&Plato搭建多轮对话模型

近年来,机器人对话应该是NLP领域最火热的领域之一了。几乎每一个手机操作系统都内置了对话机器人,智能音箱的最大卖点之一也是智能对话。那么,这种对话是如何实现的呢?我们可不可以自己定制,训练自己的对话机器人呢?回答当然是肯定的。今天,我们就尝试用百度开源模型Plato训练一个对话模型。 下载安装命令 ## CPU版本安装命令 pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle ## GPU版本安装命令 pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu 百度Plato-2对话模型 Plato是百度推出的一个多轮对话模型。该模型的最大改进在于通过引入离散隐变量实现了对话场景中多回答中的择优,即,对于同一个问题,实现不同场景下的不同回答的选择。最新推出的Plato-2在中英文效果上,已全面超越 Google Meena、Facebook Blender、微软小冰等先进模型。 图一:Plato-2模型框架 模型的整体框架如图一所示。该模型采用了经典的Transformer结构,通过注意力机制提高了模型针对不同长度对话的生成效果。隐变量z的引入,使预训练模型依据z可以生成多种回答,最终从多种回答中择优。在训练中,该模型采用两阶段训练的方法。第一阶段,基于表现良好的预训练模型,训练出一对一回答的模型;第二阶段,引入评估和隐变量z,训练出一对多回答的模型。模型的具体原理可以参考原论文,论文地址: https://arxiv.org/abs/2006.16779 对话模型训练工具 飞桨Knover工具包 百度飞桨推出的Konver工具包是一个非常强大的对话模型训练工具,我们可以通过Konver工具包快速地训练属于自己的Plato模型。Knover工具包目前支持了Plato-2模型的训练。具体参考链接:https://github.com/PaddlePaddle/Knover。在这里,我们解释一下Knover工具包中一些常见的问题。 1. 工具包分析 我们可以用train.py来进行微调训练,用infer.py 导出想要的结果。这里介绍一下这个模型的一些代码细节。 package文件夹中存放了其自带的试验数据的词集,语句切分模型(spm.model, 即sentencepiece model,这个模型用在语句的预处理上,必须给定),以及模型的细节参数(词集大小,隐含层个数,激活函数等等,具体查看package/dialog_en/24L.json。 models文件夹存放了模型的各个子模块,plato模块也在其中。data文件夹存放了实验用的小文件。tasks文件夹中包含了模型两种应用任务的实现,包括“下一句语句预测”和“会话生成”。需要注意的是,这个应用任务的选择是必须给出的,对应参数 --tasks, 分别写作NextSentencePrediction和DialogGeneration。不过实测只有DialogGeneration可以生成预测语句,NextSentencePrediction并不能生成预测语句(为打分模型,负责对回答的效果打分,以便Plato模型选择最佳的回答)。 需要指出的是,在infer.py中需要指出需要保存的内容,对应参数 --output_name,输出结果有3项:data_id, score,和response(response在NextSentencePrediction中并不生成),同时,需要在子目录创建output文件夹,否则会报错(因为源码中并没有自动创建这个文件夹,如果微调中保存了checkpoints,则会自动创建output文件夹)。 2. 常用参数 这里需要指出,--do_generation这个参数,推测是手动确定执行任务是否是生成句子的任务的,由于不需要提前指定,所以默认一直是False,但是这会在infer任务中报错,而且对于NSPModel来说,并不存在这个参数,但是在infer时仍然会报错。解决的方法是在执行Plato时加上--do_generation参数并赋值为True。 --init_pretraining_params 预训练模型所在文件夹,如果需要加载(当然需要)预训练模型需要给出这个参数 --init_checkpoint 保存节点的所在文件夹,如果给出了init_checkpoint则从该文件夹初始化训练参数(等于覆盖了init_pretraining_params的参数) train.py --train_file 训练文件地址 --valid_file 评估文件地址 --model 用到的模型名称:Plato:plato;NSPModel:next_sentence_prediction model --config_path 模型细节参数配置文件,如24L.json --task 模型应用任务 NextSentencePrediction;DialogGeneration;UnifiedTransformer --vocab_path 词集路径 --spm_model_file sentencepiece model文件的路径 --num_epochs 训练周期数 --log_steps 输出训练详情的间隔步数 --validation_steps 评价间隔步数 --save_steps 保存间隔步数 infer.py --infer_file 需要推断的文件 --output_name 需要保存的对象,response;data_id;score --model 用到的模型名称:Plato:plato;NSPModel:next_sentence_prediction model --config_path 模型细节参数配置文件,如24L.json --task 模型应用任务 NextSentencePrediction;DialogGeneration;UnifiedTransformer --vocab_path 词集路径 --spm_model_file sentencepiece model文件的路径 训练Plato模型 1. 数据准备 Plato-2模型的输入采用了token,role,turn,position相融合的表示方式。在训练和测试过程中,我们需要搞清楚文本数据需要经过怎样的转化才能作为输入,以及输出数据需要怎样的处理才能转换成文本。目前我们可以获取各种开放的对话训练集,如百度千言数据集和清华开放数据集。目前飞桨正在进行的千言多技能会话比赛中,报名即可下载多个对话数据集,我们即用这些数据集进行以下的训练。 这里也号召有兴趣的朋友参加千言多技能会话比赛,奖励多多哟!地址在此: https://aistudio.baidu.com/aistudio/competition/detail/55 1.1 中文分词 中文必须面对的一个问题就是如何实现分词。在公开的开放域对话数据集中,大多数已经做了分词,然而真实场景中语句是不可能时时刻刻都被分词了的。在Knover的源码中,对输入的处理是通过了sentencepiece工具(BERT也使用的这个)。sentencepiece提供了一种方便快捷的分词操作,我们可以直接将整个数据集放进去,设定分词的单元数量,然后等待训练出一个好用的分词模型(会输出一个预训练模型,之后对每个语句都会用这个模型进行编码和解码,即分词,转换成数字编码,输出再转换回句子)。 Knover中训练必须输入的参数spm_model,就是对应sentencepiece的预训练模型。我们当然可以自己训练一个sentencepiece的预训练模型出来,但是考虑到分词模型对效果的影响,推荐大家使用千言多技能对话中给出的baseline模型(luge-dialogue)中附带的spm.model文件,这个文件分词的效果已经非常出色了。当然,别忘了搭配词表vocab.txt使用。 仔细分析luge的spm.model我们可以发现,这个预训练模型其实是根据已经分词的句子训练的,虽说如此,因为分词单元足够多,也覆盖了所有常见的单个中文词。我们可以直接把语句送入得到编码,也可以先用jieba分词预先分一次,然后再编码。用sentencepiece模型的例子如下: importsentencepieceassp importjieba text="我今天做了一顿丰盛的晚餐!" SPM=sp.SentencePieceProcessor() SPM.load('spm.model') #直接分词 ids=SPM.encode_as_ids(text) print(ids) print(SPM.decode_ids(ids)) #先用jieba分词,再用sentencepiece编码 text=''.join(list(jieba.cut(text))) ids=SPM.encode_as_ids(text) print(ids) print(SPM.decode_ids(ids)) 1.2 文本的输入 Plato对文本输入的支持还是挺多样化的,它支持直接输入原始文本,也支持输入经过tokenize的分词序列,或者是已经编码(encoded)的数字序列。但是无论Plato支持的格式如何,在进行训练和预测之前,都会转换成能够被识别的标准格式。在Knover中,这个格式是通过定义的Record完成的。Record的定义如下: fromcollectionsimportnamedtuple Record=namedtuple("Record",fields,defaults=(None,)*len(fields)) 在解释fields的值之前,我们先来思考一下Plato需要哪些输入。在完成一段对话时,我们通常会综合对话的历史和自己所知的历史知识来进行判断,来决定自己将要回答什么。而在对话生成中,这些信息也是需要考虑的。因此,Plato需要的输入有两个,首先,是当前对方的问话,其次是已经进行过的历史对话信息,最后是背景知识。 由于各种条件的限制,背景知识可能并没有办法获取,所以至少需要的是已进行的历史对话信息,和此时对方的问话。进一步,我们需要考虑更多的信息:如果纪录了历史对话,我们如何判断每段对话的起始位置,如何判断从什么时候开始生成需要的回答,在训练集中,我们还要知道哪一部分是训练中给出的回答用于调整模型的参数。我们通过图二可以直观地看出这些输入信息的复杂性: 图二:Plato的输入结构 上图给出了Plato模型需要的输入,当然这些是以Embedding的形式给出的,而Embedding是在模型中转化的,它在转化之前是以数字编码存在的。Embedding现在已经是语言处理技术的标配了,它把每一个标记映射到空间中,增加其表征能力。我们暂时忽略最前边的latent,它是表示不同回答方式的隐变量,用于Plato在众多可能回答中选择正确的回答,我们这里不关心这个是怎么实现的,所以不展开讨论。在latent之后,有contex和response两个内容,其中context包含了众多信息:历史对话,背景知识,以及对话与对话之间分隔的符号[EOU], [BOU]等等,如果有背景知识的话,也会列到context中response则是训练中需要的部分,在测试中这一部分是空的。 TokenEmbeddings表示各语言单元的Embedding(词向量);RoleEmbeddings是各个语言单元在其中扮演的角色,这个主要是用来区分内容是context(EA)还是response(EB)(亦或是背景知识,背景知识可以作为response的角色,也可以单独成为一类,即EC);TurnEmbeddings表示每一部分在当前回合中的相对回合数;PositionEmbeddings则是每个语言单元的位置,一般是range(0, len(context))。 知道了这些,我们回到Record上来看这个输入应该怎么得到。由定义可知,Record是带名称的元组,这样我们立马可以知道,这个元组是通过名称来调用其中的内容的。fields的内容是什么呢?从官方的源码中可以总结出:fields = ["token_ids", "type_ids", "pos_ids", "tgt_start_idx", "data_id"]。也就是说,输入需要给出5个部分,token_ids就是处理过的语言单位的编码;type_ids就是个语言单位扮演的角色,是context还是response;pos_ids是各个语言单位的位置;tgt_start_idx是回复生成的开始位置,也即context的最后一个词的位置;data_id就是这个训练样本的标记。 如下给出一个例子,可以清楚的知道一个输入是如何形成的: fromcollectionsimportnamedtuple fields=["token_ids","type_ids","pos_ids","tgt_start_idx","data_id"] Record=namedtuple("Record",fields,defaults=(None,)*len(fields)) #新的会话 question ='我刚刚去动物园了。' #历史对话 history ='你好?[SEP]你好,谈谈你自己吧?[SEP]我今天过得很开心呢![SEP]是嘛,你今天干了什么?' #背景知识 background ='天气:晴朗,地点:北京,人物:男孩,动物园,熊猫' #回答 answer ='北京动物园吧,那里的熊猫很受欢迎呢!' question=SPM.encode_as_ids(question) history=[SPM.encode_as_ids(text)fortextinhistory.split("[SEP]")] background=SPM.encode_as_ids(background) answer=SPM.encode_as_ids(answer) token_ids=[] type_ids=[] data_id=0#如果样本多的话,会按排序进行标记 token_ids+=[0]+background+[2]#0表示语句开头,2表示句子结尾 type_ids+=[0]+len(background)*[0]+[0]#0表示context类,1表示response类 forlineinhistory: token_ids+=line+[2] type_ids+=len(line)*[0]+[0] token_ids+=question+[2] type_ids+=len(question)*[0]+[0] token_ids+=[0]+answer+[2] type_ids+=[1]+len(answer)*[1]+[1]#注意符号的变化 fields_value={} fields_value["token_ids"]=token_ids fields_value["type_ids"]=type_ids fields_value["pos_ids"]=list(range(len(type_ids))) fields_value["tgt_start_idx"]=fields_value["pos_ids"][-1] fields_value["data_id"]=data_id record=Record(**fields_value) print(record) 1.3 文本的转换 得到record以后,Plato还会将其中的各个标签的元组分别转换成矩阵,这里涉及到填充的过程,由于与其他文本填充的操作基本相同,这里不再赘述。 2. 训练模型 对于Plato-2模型来说,其训练包括两个过程:首先,训练出一个一对一的对话模型(UnifiedTransformer),然后基于这个模型,训练Plato模型。Plato模型的模型结构和UnifiedTransformer很接近(参数中多了一个latent_type_size)。 2.1 配置准备 由于在训练模型的时候,需要输入--config_path,这个参数用来读取模型的配置(Transformer层数量等等),这里我们需要定义两个模型的配置文件(**.json)。如下参数生成两个配置文件,配置即为我数据集中附带的模型的配置,如果有兴趣和算力,可以自己改配置训练,最有效的参数是num_hidden_layers和hidden_size,增加这些值会增加模型的规模。 importjson ##定义UnifiedTransformer的参数 key={'pre_encoder_cmd':'d','preprocess_cmd':'n','postprocess_cmd':'da','post_cls_cmd':'n','cls_bias':True, 'attention_probs_dropout_prob':0.1,'hidden_act':'gelu','hidden_dropout_prob':0.1,'hidden_size':768, 'initializer_range':0.02,'max_position_embeddings':512,'num_attention_heads':12, 'num_hidden_layers':12,'type_vocab_size':2,'role_type_size':32,'vocab_size':30004} f=open("12L.json","w") json_data=json.dump(key,f) f.close() ##定义Plato的参数 key={'pre_encoder_cmd':'d','preprocess_cmd':'n','postprocess_cmd':'da','post_cls_cmd':'n','cls_bias':True, 'attention_probs_dropout_prob':0.1,'hidden_act':'gelu','hidden_dropout_prob':0.1,'hidden_size':768, 'initializer_range':0.02,'max_position_embeddings':512,'latent_type_size':20,'num_attention_heads':12, 'num_hidden_layers':12,'type_vocab_size':2,'role_type_size':32,'vocab_size':30004} f=open("12L_P.json","w") json_data=json.dump(key,f) f.close() 2.2 训练一对一模型(UnifiedTransformer) 用命令行的方式来调用.py文件进行训练,对于模型的训练,我们可以用Knover工具包中的train.py文件进行。代码如下: pythonKnover/train.py\ --modelUnifiedTransformer--taskDialogGeneration--vocab_pathKnover/config/vocab.txt--spm_model_fileKnover/config/spm.model\ --train_filepro_data/train.txt--valid_filepro_data/valid.txt--data_formatnumerical--file_formatfile--config_pathKnover/config/12L.json\ --init_checkpointKnover/latest_model/ut_model\ --in_tokensTrue--batch_size16000-lr1e-5--warmup_steps1000--weight_decay0.01--num_epochs20\ --max_src_len384--max_tgt_len128--max_seq_len512\ --log_step100--validation_steps20000--save_steps5000\ --save_pathKnover/output\ --is_distributedFalse\ --is_cnTrue\ --start_step 2.3 训练一对多模型(Plato) 用3.2中得到的模型,继续训练Plato模型。由于是接着3.2模型进行的调整,--lr最好不要设置的过大(3.2模型--lr的十分之一即可)。注意更改配置文件,否则会报错。 pythonKnover/train.py\ --modelPlato--taskDialogGeneration--vocab_pathKnover/config/vocab.txt--spm_model_fileKnover/config/spm.model\ --train_filepro_data/train.txt--valid_filepro_data/valid.txt--data_formatnumerical--file_formatfile--config_pathKnover/config/12L_P.json\ --init_checkpointKnover/latest_model/pt_model\ --in_tokensTrue--batch_size1000-lr1e-5--warmup_steps1000--weight_decay0.01--num_epochs20\ --max_src_len384--max_tgt_len128--max_seq_len512\ --log_step100--validation_steps20000--save_steps100\ --save_pathKnover/output\ --start_step\ --is_cnTrue 3. 保存模型 当Plato训练完后,我们可以保存相应的模型,以较少模型参数的容量占用。我们需要把NSPModel和Plato模型分开储存,代码如下: ##保存NSPModel pythonKnover/save_inference_model.py\ --modelNSPModel\ --taskNextSentencePrediction --vocab_pathKnover/config/vocab.txt--spm_model_fileKnover/config/spm.model\ --init_checkpointKnover/latest_model/pt_model\ --inference_model_pathNSP\ --config_pathKnover/config/12L.json ##保存Plato pythonKnover/save_inference_model.py\ --modelPlato\ --do_generationtrue\ --taskDialogGeneration\ --vocab_pathKnover/config/vocab.txt--spm_model_fileKnover/config/spm.model\ --init_checkpointKnover/latest_model/pt_model\ --inference_model_pathPlato\ --config_pathKnover/config/12L_P.json 训练模型的应用 在模型训练完之后,便用训练后的模型做一些应用了。比如生成下一句话,或者进行多轮对话。 1. 对话生成 我们可以直接用Knover提供的infer.py生成下一句话。我们可以通过生成的NSPModel和Plato进行上述操作,代码如下: pythonKnover/infer.py\ --modelPlato--taskDialogGeneration--vocab_pathKnover/config/vocab.txt--spm_model_fileKnover/config/spm.model\ --infer_filepro_data/test.txt--data_formatnumerical--file_formatfile--config_pathKnover/config/12L_P.json\ --init_pretraining_paramsPlato--nsp_inference_model_pathNSP--ranking_scorensp_score\ --batch_size1\ --max_src_len384--max_tgt_len128--max_seq_len512\ --output_nameresponse\ --do_generationTrue--num_samples20--topk5--is_cnTrue\ --do_generationtrue--save_pathKnover/output--log_step1 2. 用Paddlehub实现多轮对话 PaddleHub是飞桨预训练模型应用工具,开发者可以便捷地使用高质量的预训练模型结合Fine-tune API快速完成模型迁移到部署的全流程工作。PaddleHub提供的预训练模型涵盖了图像分类、目标检测、词法分析、语义模型、情感分析、视频分类、图像生成、图像分割、文本审核、关键点检测等主流模型。更多详情可查看官网,链接: https://www.paddlepaddle.org.cn/hub 2.1 英文多轮对话 在Paddlehub中已经集成了两个plato对话模型,分别是plato2_en_base和plato2_en_large。其中,第一个是小模型,占用1.2G;第二个是大模型,占用12G。小模型可以在4G显存以上的电脑上直接运行,但是如果需要运行大模型,则至少需要一块16G的V100了。官方给出的这两个模型其实对话效果已经很棒了,特别是大模型,效果相当惊艳。然而,遗憾的是并不支持中文对话。如果实在想用英文对话,可以用几个简单的代码实现该模型的调用: importpaddlehubashub module=hub.module("plato2_en_base") #直接产生对话: text="whatyouwanttosay" response=module.generate([text]) #多轮对话 withmodule.interactive_mode(max_turn=3): your_words=input() response=module.generate(your_words) print("robotanswer:%s"%response) 其中,module在非对话模式(interactive_mode)下,需要输入一个储存多个问句的list;在对话模式下,则每次输入一个问句。 2.2 实现中文多轮对话 当然,只有英文对话是不够的,我们不是已经有了中文模型了吗?通过对官方hub模块的修改,我们可以将自己的模型嵌入进去,实现中文对话! 当你调用了一次官方的plato2_en_base模型后(为什么我写plato2_en_base呢?因为plato2_en_large也跑不动啊!除非你有16G显存的显卡),对应的模型已经保存到了paddlehub的离线模型库中,你可以在C:\Users\你的计算机名\paddlehub\modules\路径下找到自己下载的plato2_en_base文件夹。 首先,我们来分析一下官方模块的组成部分,如下,当我们把plato2_en_base下载下来后,可以看到其主要由以下几个部分组成: 图三:plato2_en_base组成 我们需要改的只有红线标出的部分。首先我们要准备的东西有:save_inference_model.py导出的NSPModel和PlatoModel,分别对应图中的NSP和Plato;查询字典vocab.txt以及sentencepiece预训练模型spm.model。这些文件分别放到图中所示的对应位置。 以上工作完成后,如果你确保了你替换的文件都是按照官方模块中的名字进行的命名,那么你可以直接进行调用,即用官方的名称调用。当然,稍微有强迫症的人可能并不想用官方的名字,我们可以对module进行如下更改来更改模块的名字: name即你想更改的名字,在调用模型时可以用这个名字来进行搜索。当然,如果你的模型时另外存到了其他地方,你可以用hub.module(directory=dirs)而非hub.module(name)来调用,dirs直接指定到你自己的模块所在的文件夹。更进一步地,你也可以对模块的文件夹更改名字,但是需要注意的是,如果你更改了文件夹的名字,记得将所有py文件中的import选项与文件名相关的import进行更改,即类似from plato2_en_base import ...字段的plato2_en_base更改为你想要定制的文件夹名称。 经过这些简单的操作,我们就可以通过以下几行简单的代码进行自己模型的对话了! importpaddlehubashub importos os.environ["CUDA_VISIBLE_DEVICES"]='0' module=hub.Module(directory='plato2_cn_small') withmodule.interactive_mode(max_turn=3): whileTrue: human_utterance=input() iflen(human_utterance)>0: print("You:"+human_utterance) robot_utterance=module.generate(human_utterance) print("Robot:%s"%robot_utterance[0]) else: break 最后,下边是一个对话展示: ​ 相关模型我已经公开到了AI Studio上,项目链接: https://aistudio.baidu.com/aistudio/projectdetail/1197592 下载安装命令 ## CPU版本安装命令 pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle ## GPU版本安装命令 pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu >>访问 PaddlePaddle 官网,了解更多相关内容。

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册