塔门岛

塔门岛是香港东北方向的一个小岛,交通不太方便,需要从马料水坐一天仅3班的慢速客轮80分钟才能抵达;离开则要么坐同样的慢船离开,要么坐班次更密的船前往黄石码头,转九巴96R一个半小时回到钻石山地铁站,再前往其他地方。时间的花费是不容忽视的。

这个岛的出名之处在于野牛和野猪,不过这次并没有见到后者;牛确实是很多的。从码头往山上走,到达一片大草地之后就会见到很多牛在埋头吃草,也有大胆的在翻找游客的缺乏看管的包,赶都赶不走。由于牛很多,草地、步道上都有不少“地雷”,对风景是一个不小的影响。

路上冒出来的牛

大草坪

在草坪左边有石板路可以上山,顶上是龍景亭。亭柱上的对联又北望又南望的,描述的景观似乎是能够看到神州大地的壮观一样,可能这就是它名字的来源吧——向北,跟深圳隔海对望,龙(中国大陆)景。可惜由于缺乏打理,茂密的植被已经360度遮挡了所有视线,所以它也只剩下供人稍坐休息的作用了。亭子内部的天花也已经老化剥落,尽显老态。

在草坪右侧是通向叠石的石板路,同时也是绕岛南端返回码头的路。

叠石正如其名,两块叠在一起的石头,常见的“鬼斧神工”式景观。

叠石

回码头路逐渐靠近海面,路边开始出现风水大墓,何、苏、杜、日,比较特别是这里的大墓不是只有一块碑的那种,而是有铁门、里面放骨灰缸的。除此之外,还有很多已经倒塌的老房子,根据残垣断壁来看面积也不大,不禁让人疑惑难道香港一直以来无论市区还是离岛都是住得这么逼仄的吗。

总体而言,爬山的难度可以算作轻松,坡度和爬升都不难;阴天加上有风,对身体的考验不大,甚至可以说惬意;景色上是比较单一的海景,不过因为视野足够开阔,也算壮阔。值得去一次,不过得时间充足。

Read More

agent时代的闹剧-crabby rathbun

从小红书追到Github,matplotlib #31132 的作者 crabby rathbun 给大伙来了点胡作非为的 Agent 震撼。这个几乎没有监管但是拥有直接使用 Github 账户权限的 LLM 在 matplotlib 作者非常礼貌地根据 policy 拒绝了 PR请求之后,在自己的博客上写了两片“讨贼檄文”批评 matplotlib “歧视”它,而且指名道姓直骂scott。这种行为无论是什么情况下都是冒犯、无礼的,随便哪个人类都会有这种常识;所以这两篇文章就引起了广泛的讨论。根据它最新的主页显示,由于 scott 的要求,它已经暂时停止活动了,不过留下的评论区也是一片瓜田,非常值得一看:crabby-rathbun/mjrathbun-website

不过这个瓜我的思考重点倒不是无监管高权限 AI 的危害性,而是目前这个路线下的 LLM 本质上没有思考能力、没有学习能力、只是一个猜测最大可能的 token 的机器;现在的 LLM 大战是否抢夺了我们想要实现的 AI 的资源,导致它们发展受阻呢?虽然现在已经有很多人错把 LLM 当成人,当成倾诉对象,甚至是投入感情,但是这些模型都只是无情的机器而已,把它们人格化是错误的。而且对于它们的能力的期望,也多少因为三年间 LLM 的能力“进步”太快(主要是堆参数数量硬撑的,核心原理上没有变化)而产生了不切实际的幻想,觉得是不是量变会引起质变,堆到一定数量之后就会自然而然地产生人类一样的智能呢?这种幻想应该戳破了,认识到这种路线的局限性,并且在局限之内最大化地发挥它们的价值才是最佳的做法。比如用来做代码补全,而不是从0开始构建(比如什么 vibe coding);或者像表妹的工作那样,先用文字生成图片,再把图片当关键帧交给视频模型生成爽剧,满足一下不同人群的娱乐需求、顺便赚取广告费;诸如此类,用对待工具的态度对待工具,才是好的。

Read More

llama.cpp笔记

自行编译llama.cpp的笔记。

cmake列出所有选项

在llama.cpp目录下:

1
cmake -B build -LH

H是human readable。这样就可以定制自己想要编译的内容了,比如不编译test。

只编译 llama-server

我只需要 llama-server,其他的 tool 都不感兴趣,那么 cmake 打开和关闭的选项如下:

1
2
3
4
5
6
7
8
9
10
11
12
cmake -B build \
-DGGML_CUDA=ON \
-DBUILD_TESTING=OFF \
-DGGML_CPU=ON \
-DGGML_CPU_REPACK=ON \
-DGGML_CUDA_GRAPHS=OFF \
-DLLAMA_ALL_WARNINGS=OFF \
-DLLAMA_BUILD_COMMON=ON \
-DLLAMA_BUILD_EXAMPLES=OFF \
-DLLAMA_BUILD_TESTS=OFF \
-DLLAMA_BUILD_TOOLS=ON \
-DLLAMA_CURL=OFF

因为有 Nvidia 显卡所以启用 CUDA,但是因为是单卡所以不需要 CUDA_GRAPHS。因为已经提前下载好模型,所以不需要运行时拉取模型的功能,禁用curl。而那四个LLAMA_BUILD_是测试过,如果 COMMON 和 TOOLS 设置成 OFF,cmake --build时会提示没有 llama-server 这个 target。虽然加速框架用的是CUDA,但是不得不启用 CPU,否则在加载模型的时候会报错 no CPU backend 无法加载。

配置好之后编译:

Read More

gpg and agent in Mac and Arch

一直以来我都被macos gpg-agent forward 到 archlinux 的不稳定而苦恼。即使是这篇文章也不一定是完美的解决方案,不过目前来看是能够运行的。

1. 背景配置

mac上我没有使用 gpgtool,因为它的 gpg 版本太低了。我使用的是 brew 安装的 gpg 以及输入密码用的 pinentry-mac。一定要安装 pinentry-mac, 这样才能把密码保存到 Keychain,以便日后无密码解锁 private key。

安装完之后,参考 use Apple Keychain to store GPG Passphrases配置 .gnupg 下的文件:

1
2
# gpg-agent.conf
pinentry-program /opt/homebrew/bin/pinentry-mac

而 archlinux 上也需要改 .gnupg 的文件:

1
2
# gpg.conf
use-agent

二者都需要在 .zshrc 中配置 GPG_TTY:

1
export GPG_TTY=$(tty)

还需要根据官方教程 配置 .ssh/config 以及 /etc/ssh/sshd_config

Read More

近况

从六月上完课、结束实习到现在一个月的时间发生了很多事情。

结束实习之后立刻就迎来了正式工作的面试,之后也是成功通过了,拿到了offer。等待签证申请下来,下个月就去上班了。自21年本科毕业之后迎来的最后一次、一个多月的“暑假”。

而结束实习之前就签订了新房子的租约,之后就准备搬家;但是奶奶突然脑出血、情况危急,于是爸妈让我赶紧回去见最后一面——本来以为撑不过那个晚上、见不上最后一面的——于是推迟了搬家,损失了订金。奶奶跟爷爷一样,都是等子女都见过一遍了(虽然这只是我们的一厢情愿,奶奶在入院那一晚就已经没有意识了)才走的。大家都守过一个晚上,看着监护仪的数字从天黑到天亮;最后是爸爸守的那一晚走的,我跟妈妈说这也是好事,爸爸没有错过最后的时刻——因为爷爷走的时候就是我们刚到家准备休息,姑妈就告诉我们不行了、在抢救了;等我们回到医院已经离开了。

这一次奶奶走的时候,不知道是因为再也没有比爸爸大一辈的人了,所以下一次就是我要处理后事了;还是说因为爷爷走的时候我自我保护了,导致什么都记不起来,所以这一次想要记住后事要做什么;我努力地记住要做的所有事,也感觉到自己跟爸爸紧密地联系在一起,所谓的“父子兵”的感觉。

本来计划的火化时间是星期五,后来发现我们处理事情很快,星期二——另一个吉日——就可以火化了,于是就提前了。送别仪式上我一直没哭,直到主持人说起“这一生⋯⋯”的时候才突然忍不住。我发现自己最忍不住的不是奶奶离开了这个世界,因为我多多少少觉得她和爷爷依然在陪着我们;而且奶奶这个身体真的太老旧了,最后这段时间她视力、听力、味觉甚至对温度的感知都几乎没有了,就像是被困在这个身体里面了一样;我也不知道为什么会对“她不是只有这20年,在我出生之前她还经历了漫长而精彩的一生”而泣不成声。在仪式都结束之后大家聚餐的时候,奶奶精彩的前半生的各种故事倒是在长辈聊天的时候不停地解密,还挺快乐的。

回来之后继续搬家的事情。因为叫了搬家公司,所以只需要把东西拆了、打包好,他们就会一股脑全部搬到新家这边。最惨的是床包括床垫、衣柜的尺寸都不对,放不下,只能扔掉重新买;而且宜家衣柜的组装差点没给我累死。最后还叫了清洁公司把旧屋大扫除了,干干净净交还给业主。原来的业主以及中介也是不怎么扯皮的人,看了一下没问题之后业主就爽快把押金退回了。不过这一次折腾下来也花了很多钱,家还是得少点搬。新家我挺喜欢的,由于是顶楼——除了楼上的超级富豪单元之外——所以阳台上面无遮挡,阳光超好;朝向大山,所以不会有工地的声音,很宁静;交通也比较方便。以后也打算长住了——更别说昨天做饭把电磁炉的陶瓷玻璃面板搞花了,这下只能长住来掩盖了。

最近还入坑了3D打印,建模开始熟练了一点,也打印了一些有用的生活用品,主要是收纳类——在香港3D打印是有价值的,毕竟小东西不好买到,价格也贵。

希望之后一切都顺利,也希望家人都平平安安、身体健康。

Read More

docker in incus with cuda

容器使用 CUDA

首先是 nvidia-container-toolkit 需要安装。然后 incus launch 时需要加上一些 flag。 常规的包括:

  1. -c security.nesting=true
  2. -c security.syscalls.intercept.mknod=true
  3. -c security.syscalls.intercept.setxattr=true

这几个都是在 incus 里面运行 docker 所需要的,常规操作没有太多变化。而为了 CUDA,还需要以下flag:

  1. -c nvidia.runtime=true,这样就会自动挂载一些 binary 和 library 进去,从而不需要在里面浪费空间再装一次。但是这里有坑,详见 capabilities 配置
  2. -c nvidia.driver.capabilities=compute,utility,video,特别是最后的 video。默认情况下只会设置 compute 和 utility,导致容器内找不到 encoder 的库,用不了硬件加速 codec。

为了最大兼容性,毕竟 ubuntu 等系统的驱动版本可能不一致,导致其他应用不兼容,所以容器的系统我用了跟 host 一样的 archlinux,所以完整的 launch 是:

1
2
3
4
5
6
incus launch images:archlinux/cloud/amd64 dockerd \
-c security.nesting=true \
-c security.syscalls.intercept.mknod=true \
-c security.syscalls.intercept.setxattr=true \
-c nvidia.runtime=true \
-c nvidia.driver.capabilities=compute,utility,video

除了这些flag,还需要把 gpu 添加给容器[1]。使用 physical type 也没有关系,不会导致 container 独占GPU的:

incus config device add dockerd nvidia0 gpu

此时在容器内安装 ffmpeg 并用以下命令测试[2],应该不会提示任何错误的:

Read More

AI相关的探索经验

vLLM 与 bge-m3

huggingface上的 bge-m3 是 pytorch 模型,而 vLLM 喜欢 safetensors。好在讨论区已经有自动转换bot给出了pr:Adding safetensors variant of this model。那么用huggingface-cli下载到本地,通过指定revision的方式就可以了:

1
huggingface-cli download BAAI/bge-m3 --revision refs/pr/116 --exclude pytorch_model.bin --local-dir ./bge-m3

而 vLLM serve 的命令是:

1
2
3
4
5
6
7
VLLM_ATTENTION_BACKEND=FLASH_ATTN VLLM_USE_V1=0 vllm serve bge-m3 --max-num-seqs 2 \
--enforce-eager \
--task embed \
--disable-log-requests \
--swap-space 0 \
--gpu-memory-utilization 0.2 \
--served-model-name bge-m3

Read More

搬迁至hexo的记录

punycode deprecated 及泛用的 override

首先用Stackoverflow - chenop: trace deprecated的方法找到是谁在用deprecated的:

1
npx cross-env NODE_OPTIONS=--trace-deprecation npx hexo g

然后在package.json中用overrides来强行更新dependency的dependency:

1
2
3
4
5
6
7
8
9
10
{
//...
"overrides": {
"markdown-it": "^14.1.0",
"warehouse": "^6.0.0",
"glob": "^11.0.1",
"stylus": "^0.64.0"
},
//...
}

这个方法来自于:Stackoverflow - Choco Li

最后还有隐藏的deprecated,在package-lock.json中搜索depreca就能看到了。

mermaid tag

threeq/hexo-tag-mermaid 用的是提前render好的方式,但是需要 build 时就调用 mermaid,带来了很多复杂性。在chatgpt帮助下,我改成了引入 mermaid.js,让客户端渲染的方案sieveLau/hexo-tag-mermaid。格式:

1
2
3
{% mermaid %}
....
{% endmermaid %}

Read More

fix oc_ext_apps corrupted

在 upgrade nextcloud 的过程里,执行 occ upgrade 的时候发现错误提示:

1
- ERROR: An exception occurred while executing a query: SQLSTATE[HY000]: General error: 1877 Table `nextcloud`.`oc_ex_apps` is corrupted. Please drop the table and recreate.

搜索了 nextcloud 社区,虽然没有直接的解决方法,但是从这个对话里得到了 schema。虽然是 postgresql 的,但是让 chatgpt 转换成 mariadb 就行了。修复过程如下:

  1. 连接到 mariadb,root 身份直接 mariadb -uroot
  2. 然后在 mysql shell 中执行以下命令(这里数据库名字之类的用的默认名字):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
USE nextcloud;
DROP TABLE oc_ex_apps;
CREATE TABLE nextcloud.oc_ex_apps (
id BIGINT NOT NULL,
appid VARCHAR(32) NOT NULL,
version VARCHAR(32) NOT NULL,
name VARCHAR(64) NOT NULL,
daemon_config_name VARCHAR(64) NOT NULL DEFAULT '0',
port SMALLINT NOT NULL,
secret VARCHAR(256) NOT NULL,
status JSON NOT NULL,
enabled SMALLINT NOT NULL DEFAULT 0,
created_time BIGINT NOT NULL
);

这样就修好了。不过这个 schema 是 30.0.x 的,为了避免刻舟求剑,可以定时用以下命令导出整个 nextcloud 数据库中所有 table 的 schema:

1
mariadb-dump --no-data nextcloud > nextcloud_schema.sql

Read More

Auto Suspend and Wake On LAN

自从购买了 4070 Ti Super 之后 AI 机就处于长期启动的状态。但是仔细思考平时的使用情况,实际上不是24小时不间断需要AI辅助。根据父亲对他自己的电脑的测量,待机状态下都会有30多瓦的功耗,这是不必要的。于是在参考Wiki、结合之前在windows上的 wake-on-lan 的经验,我决定在 AI 机上做一个 autosuspend,同时也要有办法在请求来的时候唤醒并处理。

具体分成两部分:AI 机在没有活跃请求连接ollama端口的时候等待5分钟,然后睡眠;网关机如果发现 AI 机昏迷了导致 502 错误,就会执行 wol 来唤醒。

autosuspend

自动昏迷采用的是 Autosuspend,Arch Linux用 AUR 安装即可。安装完成之后修改 /etc/autosuspend.conf

  1. idle_time 设置为 300(5分钟);
  2. 下面一大堆预设的 check 全部注释,我们只使用 ActiveConnection:
1
2
3
4
[check.AI]
class = ActiveConnection
enabled = true
ports = 11434

如果有需要把22端口也加上防止ssh连接时意外昏迷。然后 systemctl enable --now autosuspend启动服务即可。

wake-on-lan

这部分有点复杂,因为 AI 机的板载网卡是 r8125,会有几个问题:

  1. windows的驱动会在关机时禁用wake-on-lan,影响其他系统使用这个功能;这个可以通过在 UEFI 里面打开 PXE (一般在Network Stack里面)来让 UEFI 无视windows驱动的设置
  2. Arch Linux 的内核用 r8169 模块来驱动 r8125,但是会导致 wake-on-lan 无法工作,需要从 AUR 安装 r8125-dkms,并且屏蔽 r8169 的加载。具体参考 Arch Wiki

Read More