使用 WSLg 的 vGPU 硬件加速新特性创建重度混合生产环境

一、不同版本的WSL

Windows Subsystem for Linux(简称WSL)是一个在 Windows 10\11 上能够运行原生Linux二进制可执行文件(ELF格式)的兼容层。

到目前为止 WSL 可分为 WSL1 和 WSL2 两代,其中 WSL1 代类似 Cygwin,是使用Windows 的 API 重写了一份 Linux 的 API,没有关机概念,无法使用 systemd、docker 等运行常驻服务;而 WSL2 是基于 Hyper-V 的完整虚拟机,支持 systemd、docker 等在内的常驻服务运行;最新的 WSLg 是 Windows Subsystem for Linux GUI 的缩写,该项目的目的是支持在 Windows 上以完全集成的桌面体验运行 Linux GUI 应用程序(X11 和 Wayland)。

WSLg 的 Firefox 和 Windows 下的 Firefox

简单的来说 WSLg 可以让你直接在 Windows 的桌面环境下直接运行 Linux 下的 GUI 应用,共享 Windows 的桌面,只到这一步的话,WSL 系可能还是偏向玩具+轻量级的混合生产环境,但是,最最最最新的更新,WSLg(WSL2)已支持 vGPU,可以直接调用物理宿主机的显卡。这下性质真的变了,你可以在主操作系统为 Windows 的情况下,使用 WSL2 来跑 Linux 下的重度生产环境。属实是工作生活双平衡了(bushi)。

二、WSL2 安装 + 桌面环境部署

WSL2 的安装方法和 WSL1 一致,使用 控制面板→程序和功能→启用或关闭 Windows 功能,按下图勾选 Hyper-V、适用于 Linux 的 Windows 子系统、虚拟机平台 三个选项(Hyper-V 在列表上方图没截进去)。

安装 WSL

安装完毕后按要求进行重启,之后先以管理员身份运行以下命令:

# 设定WSL版本为WSL2
wsl --set-default-version 2
# 升级WSL组件
wsl --update
# 安装 Ubuntu-20.04 发行版
wsl --install -d Ubuntu-20.04

至此 WSL2 已安装完毕,在开始菜单中找到 Ubuntu20 启动或者在任何 CMD、Powershell中键入 bash 命令即可进入 WSL2 的 Ubuntu20 环境。接下来使用以下命令安装 Ubuntu 的桌面环境:

sudo apt-get update
sudo apt-get install ubuntu-desktop

安装完毕后会发现开始菜单中多了很多图标带有 Linux 小企鹅标志的的程序快捷方式,名字也带有 “(Ubuntu 20)” 的标记,这些就是 WSLg 的启动方式了。

WSLg 快捷方式

三、vGPU 的使用

其实在 WSLg 之前,可以使用 Hyper-V 的 DDA 功能将物理机的 GPU 直接分配给虚拟机使用,来实现虚拟化的生产环境。但是使用 DDA 也存在几个问题:

  1. 无论是通过 DDA 挂载还是释放,都需要非常复杂的纯命令行设置,需要手动计算、分配内存的可用大小
  2. 通过 DDA 分配给虚拟机时,宿主机必须断开与 GPU 的访问,即宿主机和虚拟机无法同时访问 GPU

而现在可就方便多了,首先确定 Windows 10/11 的系统版本已为最新,同时安装最新的显卡驱动,vGPU 的配置就已经自动完成了。在 Linux 的环境下可以直接使用 nvidia-smi 命令来查看 GPU 状态,非常丝滑和离谱。CUDA is Ready!

在 WSL 中查看 GPU 状态

实测此时直接使用 Firefox 等浏览器还无法直接播放视频,但是使用 sudo apt-get install vlc 命令安装完 vlc 播放器和相关的解码依赖后,就可以愉快地直接在 Firefox 中使用硬件解码来播放4K视频了。

使用 WSLg 的Firefox 播放 4K 视频

至此相关配置全部完成,按照正常的 Linux 环境来用即可。当然,也许有人要问,那我直接用 Linux 不就好啦。但是实际生产过程中,总是会遇到 “如果我用的是 Windows/Linux 系统就好了” 这种情况。混合生产环境的最大优势就是在于,可以同时使用 Windows 和 Linux 系统下最好的工具,互相配合,甚至可以在 Windows 环境下通过先调用 cmd 再启动 bash 然后通过标准输入输出来整合两个环境的工具,形成工作流。

个人觉得,很多时候,决定工具上限的不是工具本身,而是使用者的技术上限和技术边界。

开源双语对话语言模型 ChatGLM-6B 本地私有化部署

ChatGLM-6B 是一个开源的、支持中英双语的对话语言模型,基于 General Language Model (GLM) 架构,具有 62 亿参数。结合模型量化技术,用户可以在消费级的显卡上进行本地部署(INT4 量化级别下最低只需 6GB 显存)。 ChatGLM-6B 使用了和 ChatGPT 相似的技术,针对中文问答和对话进行了优化。经过约 1T 标识符的中英双语训练,辅以监督微调、反馈自助、人类反馈强化学习等技术的加持,62 亿参数的 ChatGLM-6B 已经能生成相当符合人类偏好的回答。ChatGLM-6B 权重对学术研究完全开放,在填写问卷进行登记后亦允许免费商业使用。

其中一个比较关键的点是:消费级的显卡即可进行私有化部署,下文将着重介绍部署的相关步骤。

建议硬件配置:

量化等级最低 GPU 显存(推理)最低 GPU 显存(高效参数微调)
FP16(无量化)13 GB14 GB
INT88 GB9 GB
INT46 GB7 GB

不过该模型也可在无GPU的情况下部署,但是推理速度会更慢,最低需要32G内存。

一、克隆仓库

本地部署的话实际需要用到两个仓库,一个是源码仓,一个是模型仓。在操作之前请确认Git已正确安装并启用了LFS。

源码仓库:https://github.com/THUDM/ChatGLM-6B

模型仓库:https://huggingface.co/THUDM/chatglm-6b

使用 git clone 命令克隆至本地即可,由于仓库的默认名称一致,建议在克隆一个仓库后改名再继续克隆另一个仓库。模型仓库体积较大,请确保网络连接稳定。

二、安装依赖

1. 更新显卡驱动

进行下面的操作前请确认已更新最新的显卡驱动。如果显卡本身就以工作负载为主,请选择 Studio 版本的驱动。

2. Python3

首先确保 Python3 已正确安装并配置了相应的环境变量。打开命令窗口能正常调用 py 和 pip 命令说明配置正确。

3. 自动安装依赖

进入源码仓库,执行以下命令安装依赖:“““`

pip install -r requirements.txt

4. 安装 PyTorch 和对应版本的 CUBA

为了确保 Torch 版本与 CUBA 匹配,先执行以下命令移除已有的 PyTorch:

pip3 uninstall torch torchvision torchaudio

打开 https://pytorch.org/get-started/locally/ 页面,选择 PyTorch 的版本,注意 CUBA 版本的选择,然后复制如图的安装命令。

打开 https://developer.nvidia.com/cuda-downloads 页面,如果自动跳转的 CUBA 版本与要求的版本不一致,可以找到在页面下方的 Archive of Previous CUDA Releases 链接打开新的页面检索并下载安装。

三、改用本地模型

源码仓库在没有修改的情况下默认不会使用本地的模型,接下来需要修改模型引用的代码来指向本地的模型文件。建议使用 VS Code 之类的工具来进行批量的替换。

实际操作时,只需要将整个源码目录下的 “THUDM/chatglm-6b” (注意,搜索替换时一定要带上这对英文的双引号,否则可能会错误匹配)替换成第一步中克隆下来的模型的目录的路径(注意替换后的文本也需要英文的双引号,Windows 下要注意 \ 需要以转义符 \\ 的形式写入)。

四,启动 WebDemo

上述步骤全部完成后,进入源码仓库,使用下述命令启动即可:

py .\web_demo.py

启动完毕后会自动打开 Web 页面,Enjoy It!

PS:这玩意儿确实吃显存啊!

为32位.net程序开启内存地址拓展突破2G内存限制

32位的.net程序在默认情况内存占用限制为2G,而在实际使用过程中,占用超过1.3G左右(个人观察)就容易出现内存不足的报错甚至直接崩溃。而VS系列IDE附带的命令行工具其实提供了内存地址拓展功能,可以突破该限制使用4G左右的内存。

命令行工具位于VS安装目录下的一个文件夹,可以通过打开Windows的系统变量窗口来确定该文件夹的系统级环境变量(以“%”开头和结尾,可以在路径中作为变量使用),比如下图为Win11 + VS2019的组合的环境变量:“%VS160COMCOMNTOOLS%”。

Win11 + VS2019 的系统环境变量

具体工具的调用批处理文件名为“VsDevCmd.bat”,请注意,在VS2015及之前的版本中,该文件名为“VsVars32.bat”。

为了避免每次工程生成后需要手动调用,可以在项目的属性中,生成事件选项卡的“生成后事件命令行”中添加如下命令(路径请自行修改):

call “%VS160COMCOMNTOOLS%\VsDevCmd.bat” && editbin /largeaddressaware $(TargetPath)

其中“$(TargetPath)”会自动指代生成的32位程序。

配置完毕后,每次生成工程成功后,会自动调用命令行工具给程序拓展内存地址,在输出栏中,如果出现一下信息,可以视为调用成功:

4>
4> ** Visual Studio 2019 Developer Command Prompt v16.11.5
4> ** Copyright (c) 2021 Microsoft Corporation
4>
4> Microsoft (R) COFF/PE Editor Version 14.29.30136.0
4> Copyright (C) Microsoft Corporation. All rights reserved.
4>
========== 全部重新生成: 成功 4 个,失败 0 个,跳过 0 个 ==========

修改成功与否,可在程序启动的部分中加入以下代码,查看调试界面的内存占用情况。

try
{
int count = 100000000;
List lst = new List(count);
for (int i = 0; i < count; i++)
lst.Add(new int[1000000]);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}

下面两张图依次为未启用和启用后的内存占用情况,若启用后弹窗时占用能够达到4G左右,则说明修改生效。

未启用内存地址拓展的内存占用
启用内存地址拓展后的内存占用

祈&昔

三年了,变的东西太多了,有些人走了,有些人走了。

这个世界唯一不改变的就是永远在改变。

祈

吾之所祈,静坐君旁;
无论何时,不论何方。
眸内唯君,绝无迷茫;
君之美丽,汝可自详?
与君笑,叹分秒太短;
与君别,恨时间太长。
嬉笑嗟叹,皆为虚妄;
恨己无力,未来空想。
念君,心已惘;
恋君,泪千行。
心语难言,勇气皆丧;
盼归再会,却把西望。
昔

吾与爱人,天各一方;
长风难至,喜鹊也惘。
眸内唯君,仍未迷茫;
月明风清,汝可仰望?
与君别,感海角天涯;
听君叹,恨西洋难渡。
三十六朔缘难续,
六十五载皆空想。
念君,心已怅;
恋君,泪千行。
每每与梦,难追芳迹;
日日盼归,终不再望。

WordPress站点动静态分离与CDN配置

小型站点或个人项目最经常遇到的一个问题就是带宽不够。纯文字的页面在低带宽条件下体验尚可,但是当遇到图片较多,甚至有插入音视频的多媒体页面或者个人项目需要提供下载服务时,低带宽下的那个速度真就可以用惨不忍睹来形容。

提高带宽确实是一个好方法,但是带宽的价格真的就……温暖人心。高额的费用对于小型站点和个人项目来说是非常不合适的。

在此情况下,CDN(Content Delivery Network,即内容分发网络)就是一个非常不错的选择。将静态资源(譬如图像、音视频、页面js文件等)挂载至CDN上,可以有效地减轻站点的带宽负担,加快网络访问速度,最主要的是,相比于提升带宽的费用,CDN的价格真的太厚道了。同时,很多云服务提供商比如腾讯云等每个月会提供一定的免费CDN流量,对于小型站点或者刚起步的个人项目几乎可以说是免费。

关于CDN具体的实现原理,本文不进行赘述,感兴趣的可以从以下链接获取相关信息:

https://cloud.tencent.com/developer/news/358957

https://yq.aliyun.com/articles/104041

CDN的优点确实有很多,但是实际上使用的时候还是需要注意一些地方。比如上文就提到了“静态资源”这个概念,对应的也就会有“动态资源”的说法。以一个网站为例,网站的html和js文件,用到的图片等等,都是静态资源,它们除非被人为的进行修改,否则是不会发生变化的。对应的,网站中通过php、asp等方式实现的内容,比如动态的日志系统等等,这些是动态资源,需要服务器后台进行解析处理的,是会实时变化的。

在配置CDN的时候,如果只是简单的将整个站点挂上CDN,那么可能就会开始发生很多诡异的情况,比如通过日志系统发布的日志在主页没有更新出来,登入登出系统失效等等。因此,又有了一个概念,即动静态分离或叫动静分离。如同字面意思,其核心就是讲网站按照动静态资源的标准进行区分,将静态的资源挂上CDN,动态的资源直接访问源网站。这样就可以避免发生上述的种种诡异情况。

下面以WordPress站点为例,介绍具体的动静态分离方法与CDN配置。

一般来说CDN是按照域名来进行加速的,因此需要挂载CDN的资源应当放在一个新的域名下,与存放动态资源的主站区分开来。简单来说,我们需要做的就是添加一个新域名(一般来说是二级域名)→将站点动静态资源分开,静态资源放置在新域名下→给新域名配置CDN

我们先进入腾讯云的内容分发网络功能页面中的域名管理,添加新域名。在域名一栏填入作为CDN加速站点的域名,业务类型选择静态加速。源站笔者由于有自己的VPS而且带宽也还差不多,因此就选择了自有源站(注意,对应服务器上也要新建一个站点才可以),否则可以使用COS来创建CDN。回源协议由于笔者站点已配置好SSL证书,故选择协议跟随。

服务配置这里的配置比较关键,会直接影响CDN的加速效果。先简单的说一下内容和刷新时间的概念,腾讯云这里的内容即指影响的文件类型,php等动态资源配置为0即不进行缓存,其他资源配置30天则意味着缓存每隔30天刷新一次(注意,新添加的资源在请求时CDN会重新获取,不会出现文件不存在的情况),下面的配置优先级高于上面,即目前的配置是“除了动态文件以外的文件30天刷新一次”。刷新时间这个值不应配置太低,太低CDN会频繁的从源站请求资源,造成访问不通畅也起不到加速的效果。

确认提交后,回到域名管理,复制下图中CNAME栏中的地址。然后到域名解析中添加新的记录,类型选择CNAME,记录值填写刚刚复制的地址,实现对应的解析,即完成了CDN的简单配置。

目前来说,CDN已经能够正常工作了,不过还有很多特殊的配置可以进行修改。我们回到CDN的配置页面,在刚刚配置好的那一项的最后找到管理,进入对应的管理页面。切换到访问控制,把防盗链打开,填入会用到CDN加速资源的站点地址,可以搭配通配符。这样可以有效避免CDN上的资源被他人盗用,比如说CDN上可能存放了音乐文件被别的站点拿去当背景音乐或者图片被别的站点直接盗用,这样最后走的是我们自己的流量和费用了……

然后切到高级配置页,带宽封顶打开,该选项可以一定程度上避免DDOS攻击和恶意的CDN流量消耗。超出阈值可以设置为访问回源,即超出阈值了直接跳转到源站点;也可以选择返回404。HTTPS视情况配置。

至此CDN部分配置基本完成,下面就是WordPress的配置部分。

首先复制WordPress站点目录下的wp-content和wp-includes文件夹,删除不需要的部分,部署至CDN加速域名下。然后给WordPress安装WP Super Cache插件,这个插件可以重写WordPress中的部分地址至CDN来实现利用CDN加速。

安装完毕后,切换到通用页,先把缓存功能打开;然后切到CDN页,勾选“开启CDN支持”。站点地址处填写主站点的地址,off-site URL填写CDN加速站点的地址,其余配置不动,保存即可。

此时所有配置均已完成,打开浏览器的调试功能,打开主站,观察网络请求中的内容,如果图片、js文件的请求URL域名是配置好的CDN域名和主站的域名不是同一个,即说明WordPress配置CDN成功。

由于个人能力有限,文中难免会出现疏漏或错误,还望见谅。

建阁志

其实很久就想建一个自己的Blog了。

如果只是想要个博客的话,CSDN、博客园都是不错的选择,确实也没必要自己这么折腾,买服务器然后配置WordPress种种。无奈存在别人那里的东西永远说不上安全,说不准什么时候就没了,而且还有一堆广告和种种限制。索性自力更生自己建站了,这大概就是所谓的“性格使然”吧。

域名当时考虑了很多,关键字最后还是选的“licorne”,法语的独角兽,对应中国神话中的白泽(也不完全对应,一般白泽翻译为东方独角兽,还是略有区别)。我也不知道自己为什么特别喜欢这种神兽,这名字姑且就先用着了。

其实之前一直挺不喜欢写日记之类的东西,觉得麻烦而没必要。想记住的东西自然会记住,而不必借助纸笔;而不想记住的东西,索性忘了更好,更不必留下记录。但是经历了不少事情之后,对记录和日志这类的东西,还是稍微有了改观。关键的并不是记录了发生了什么事情,而是当时发生了一件事情后我的想法是什么。也许我能记住很多事情,但是当时的心情和当时的想法,不记录的话确实不会记得。

多年后,翻翻之前写的东西,让过去的自己和现在的自己说说自己身上曾经发生的故事,感觉还是挺有意思的。

这个Blog以后主要会以技术类的日志为主,可能也会有其他日常记录或者想分享的东西,当然不一定全公开就是。

总之,新Blog今天就算是正式启用了。以上废话,是为《 建阁志 》。