MoreRSS

site iconMayx修改

兴趣范围从技术到网络开发,还对编程、DIY和设计感兴趣。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

Mayx的 RSS 预览

如何使用JS通过订阅源查看文章?

2025-04-08 00:00:00

懒得写代码?那就让AI写!

起因

前段时间,我看到有些博客给自己的友链页面做了通过订阅源查看友链最近更新文章的功能,看起来挺有意思的,有点想整一个。不过对于我的博客来说,作为静态博客想要做到这样的功能估计没那么简单吧……毕竟一般的订阅软件需要隔段时间请求一下对应博客的订阅链接,然后再把结果存到数据库才行。但是我想了想,对我来说没必要做成订阅啊,我又不需要知道对应博客是什么时候更新的,只要在有人想知道的时候去请求一下订阅链接,然后展示出来就行,感觉似乎又没有那么复杂。
既然不复杂,那这个功能就让AI来做吧,正好前段时间有个朋友买了一个月的Devin.ai订阅,据说是可以自己调试代码,还能操作浏览器,而且代码基本上写出来就能用。我对这个挺感兴趣的,所以这次的功能就让它来写吧!

让AI编写代码

既然是让AI来写,至少得把我的需求说清楚,所以首先我应该告诉它:

创建一个JavaScript函数来实现Links表格中链接的RSS/Atom源预览。

  • 当鼠标悬停在表中的链接上时,检查该网站是否有RSS/Atom源,并将结果显示在一个浮动窗口中
  • 在鼠标光标后的浮动窗口中显示提要中的5篇最新文章
  • 在窗口中只包含标题和时间,不需要链接和内容
  • 跳过所有不包含RSS/Atom源的链接,而不显示任何错误
  • 当鼠标离开链接时,浮动预览应该消失

不过在正式编写之前,我还得考虑一下可行性,毕竟是很简单的功能,我不写但我不能不知道怎么写。首先让JS解析Feed数据也就是XML数据应该是很简单的事情,JS应该有自带的函数来实现这种功能。然后是获取数据,在JS中使用fetch就可以了,但是这里有个很重要的事情,浏览器请求其他网站存在跨域的问题,还好我之前在CF Workers上用cloudflare-cors-anywhere搭了个CORS代理: https://cors-anywhere.mayx.eu.org/ 。所以我应该在说明中给它说清楚:

  • 如果存在源,请使用CORS代理:https://cors-anywhere.mayx.eu.org/ 获取并解析它

随后我就开始让它编写代码了。接下来就能看到AI在浏览器和编辑器中切换,不停的进行编写和调试,等了一段时间,它把第一版代码写好了。不过也许我说的不够清楚,这个CORS代理的用法和其他的CORS代理不太一样,代理链接和被代理的链接之间需要使用“?”分开,另外第一版我也没说清楚RSS/Atom源的链接在哪,所以它选择遍历常见的几种订阅源的路径,这样有点不太好,除了速度慢,对我的CORS代理消耗也比较大。所以我告诉它代理的正确用法,以及让它假设超链接中包含“data-feed”属性,其中包含订阅源的链接,并且随便挑了个网站拿给它作为示例。
随后就能看到它继续改改改,改了几次之后我把最后生成的JS复制到浏览器上执行了一下,效果还不错,于是就把它放到我的博客上了。
它的水平还是挺不错的,至少正确的实现了功能。不过我有点担心它的代码会不会不太可靠,毕竟要从其他网站上获取数据,得避免出现XSS之类的问题,于是我把代码丢给DeepSeek-R1让它检查了一下,果不其然Devin.ai写的代码似乎有XSS的隐患,如果链接列表中标题有html标签似乎就会解析(虽然我没试过),于是根据DeepSeek的提示修改了一下,增加了一个过滤特殊字符的函数,改完又放到博客上,最终的代码就是:rss-feed-preview.js

感想

让AI全自动写代码感觉还挺方便,有种当产品经理的感觉了🤣,像这种AI就是Agent吧,这也算是我头一次使用Agent了,感觉用起来还挺不错的。不过从这次尝试来看确实AI也有一定的局限性,像是直接写出来的代码可能存在一些安全性问题,除非单独让AI检查,不然很有可能会写出功能正常但是存在漏洞的代码,所以还是得人看着点,AI搞出事故可是不负责的啊😇~

最近对博客搜索功能的优化记录

2025-04-04 00:00:00

看看其他的博客也会有新的灵感啊~

起因

前段时间,我闲来无事在GitHub上搜和我使用相同模板minimal的博客。但搜索结果中有许多人用这个模板制作的是简历或作品集,这让我有些失望。不过这倒也能理解,因为这个模版并不算博客模板,没有文章列表之类的代码,这些都只能自己写。当然多找找还是能找到一些的,毕竟这个模板在GitHub Pages中算是最受欢迎,至少符合大众的审美。像我就搜到了一个叫Guanzhou Hu的博客,他对模板的样式做了不少的改动,而且改的还挺好看的,尤其是右上角的导航栏,看起来挺有意思,只是这个源代码……导航栏有点硬编码的感觉,我不是很喜欢这种实现方式……

使用标签作为关键词进行搜索

之后我又看了看其他博客,看到了Matt Walker Blog。他没有对模板做很多改动,只是把section元素变得更宽了,但是他没有改手机版自适应的样式,导致界面基本上没法在手机上查看。不过在他的首页中,我对他把文章标签放在文章列表这个操作非常感兴趣,因为每次我都有给文章打标签,但是几乎没什么用。他的标签点进去之后会跳转到该标签下的所有文章,我其实很早就想做这个功能了,但是在不用插件的情况下Jekyll基本上做不出来这种功能,因为没有插件的情况下是不能使用Liquid标签创建文件的,我看了下他的实现,原来是提前创建好的标签页面然后进行筛选的,这个实现我也不喜欢,这样的话我每次打标签都要新建一个标签对应的页面,这种事情不让程序做我会很不爽……(其实现在的GitHub Pages构建网站都是用的Actions了,完全可以自己写一个可以使用插件的Actions来进行构建,不过我也懒得折腾了🤣)
要么还有一个选择,可以单独搞一个页面,里面有所有标签对应的文章,点击文章的标签之后使用锚链接定位到对应标签所在的位置。但这样会导致一个页面有可能有一堆相同的文章链接,结果这个页面比归档页面的链接还多,那就感觉有点糟糕了……
不过我想起来以前做的博客全文搜索功能,如果把标签作为关键词进行查询,那也能起到筛选出标签对应文章的作用吧?而且这样即使我没给那个文章打标签也能搜出来,其实也算不错的选择,另外自从我做出来那个全文搜索的功能之后也没用过几次,没有关键词的话也一时半会想不出来搜什么比较好。于是说做就做,直接把Matt Walker Blog那段在文章列表生成标签的代码复制过来,感觉好像还不错😆?
顺便我也把文章里面的标签也加了链接到搜索的功能,不过原来的代码用的是.join实现的,现在加上这个功能的话就只能老老实实用循环写了😥……

搜索后使用高亮标记关键词

上面的标签搜索效果还不错,只是有些关键词搜完之后有点难发现。我搜索出来之后怎么证明搜到的内容里面一定有对应的关键词呢?虽然从程序的角度来说这是理所应当的事情,一定是有的数据才可能被搜到,但有时候不用Ctrl+F看一眼都不知道是哪里搜到了……所以我觉得应该像其他网站一样对搜到的内容用高亮进行标记。标记应该用什么呢?用样式也许不错,不过现在的H5标签里有一个叫mark的标签可以直接用,用这个标签包裹的内容背景颜色就会变成黄色,就像用荧光笔标记了一样,这样就不需要写样式了。
至于关键词用查询字符串传过去就好了,那我该怎么做呢?我用的搜索脚本叫Simple-Jekyll-Search,它的文档其实根本没有写怎么把搜索的请求传到模版里,还好它有个关于模版的测试脚本里面有写,有个query关键词可以把搜索内容给模版渲染出来,既然做了这个功能怎么不写在文档里😅,不过这个项目已经停止,也没法提出什么建议了……
这个功能听起来相当简单,我都懒得写了,这种简单的功能直接让AI写才对!于是我把需求告诉它,让它给我实现一份,于是这就是让AI给我写的高亮关键词的JS代码(经过了一点修改):

$(function() {
    const urlParams = new URLSearchParams(window.location.search);
    const keyword = urlParams.get('kw')?.trim();

    if (!keyword) return;

    // 转义正则表达式特殊字符,避免安全问题
    const escapedKeyword = keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    // 创建不区分大小写的正则表达式(全局匹配)
    const regex = new RegExp(`(${escapedKeyword})`, 'gi');

    // 递归遍历并高亮文本节点
    function highlightTextNodes(element) {
        $(element).contents().each(function() {
            if (this.nodeType === Node.TEXT_NODE) {
                const $this = $(this);
                const text = $this.text();
                // 使用正则替换并保留原始大小写
                if (regex.test(text)) {
                    const replaced = text.replace(regex, '<mark>$1</mark>');
                    $this.replaceWith(replaced);
                }
            } else if (
                this.nodeType === Node.ELEMENT_NODE &&
                !$(this).is('script, style, noscript, textarea')
            ) {
                highlightTextNodes(this);
            }
        });
    }

    $('section').each(function() {
        highlightTextNodes(this);
    });
});

我测试了一下,非常符合我的需求,各种情况都能按照我的预期工作,虽然说功能非常简单,但是能正常运行,AI写的还是挺不错的。

近期的其他修改

除了对搜索功能的优化,我还做了些别的功能:

随机跳转文章

前段时间我看到有其他人的博客增加了一个随机跳转文章的功能,不过他的博客是动态博客,实现也比较奇葩,是渲染页面时就已经决定好要随机的文章,也就是说无论用户想不想随便看看,程序都已经随机好了。当然用着静态博客的我来说,从原理上也做不到这一点,不过既然我之前在做相似文章推荐功能时已经对搜索功能的数据进行了缓存,那么直接用缓存的内容直接随机就好了吧……所以就随便写了写,代码也极其简单:

<a href="javascript:getSearchJSON(function(data){window.location = data[Math.floor(Math.random()*data.length)].url})">Random</a>

给文章内标题添加锚链接

最近在修改我的博客的时候我更新了一下给文章生成目录的组件,在这时候我想看看它还有什么有意思的组件可以用,然后就发现了jekyll-anchor-headings,它可以像GitHub展示Markdown文件一样在标题上添加点击后就可以直接跳转到对应标题的锚链接,而且示例里也给出了怎么做可以像GitHub的风格。看起来挺有意思,所以就给自己加上了😆。

添加能跳转到原始Markdown的链接

在修改博客的时候我参考了一下Jekyll的官方文档,在这个时候发现了page.path这个变量。我想了一下这个变量可以用来链接到我的文章内容,然后就在文章标签位置的右侧加上了这个链接,为了能让它显示在右侧,我用的是float: right,但是这样会导致和文章标签不在同一行,查了一下才知道用了浮动就会强制将元素转换成块级元素,而文章标签用的是行内元素,所以对不齐,没办法就只能把这一整行都转换成块级元素了……于是代码如下:

<span style="float: right;"><a href="{{ site.github.repository_url }}/tree/master/{{ page.path }}">查看原始文件</a></span>

感想

多看看其他人的博客看来也挺不错,可以看看其他人的想法,说不定就有可以参考的价值呢……不只是文章内容,网站本身的一些功能也是作者的想法啊……而对于那些只套别人模版,没什么自己的改动的博客,那就没什么意思了(当然不会代码的那就没办法了~)。有些人说博客中只有文章才是最重要的,但我觉得对于技术博客来说网站的代码也是展示自己的部分,所以折腾博客本身也是很重要的!

在UTM中使用苹果虚拟化的各种尝试

2025-03-25 00:00:00

用官方的方式做非官方的事!

起因

在几年前刚收到MacBook Pro的时候,我曾安装过虚拟机软件UTM。但是因为我的Mac内存很小,用虚拟机的体验很差,所以就把UTM卸载掉了。不过以前还我还装过一台黑苹果,在上面也安装了UTM。
最近正好由于某些原因我需要在macOS上安装虚拟机,既然有UTM用就继续用UTM了。当然正常情况就是按正常的方式安装系统然后正常的用,这并没有什么意思。所以我想整点有意思的事情,想试试不太正常的使用UTM😝。

在UTM中使用苹果虚拟化框架安装Windows

如果用过UTM的话应该知道,UTM有很多选项,比如底层的虚拟化框架可以用QEMU或者Virtualization.framework(VZ),而QEMU的后端可以选TCG或者是Hypervisor.framework(HVF)。它们有很多特色,像TCG的兼容性最好,可以模拟任何架构的CPU,但是性能最差,HVF使用硬件虚拟化加速,只能运行宿主机架构的程序,但是性能比较好,而VZ经过了苹果官方优化,性能最好。
那么现在我想安装Windows,又想有最好的性能,那我应该选择VZ吧?可是UTM不允许我这样选择,如果选择安装Windows就会强制使用QEMU……只有Linux或者macOS(在ARM处理器)才能使用VZ……那我应该如何绕过这个限制呢?
我想起来之前让没用的主机感染木马的文章中使用了一键DD/重装脚本把我服务器的Linux系统重装成了Windows系统,那么我能不能用相同的方式先按照正常的方式用VZ安装一个Linux系统然后使用这个脚本重装成Windows?我觉得理论上应该没问题,所以就尝试了一下。
我在这之前已经安装过了一个用了VZ的Ubuntu虚拟机,新建比较费时间所以就直接把这个虚拟机复制了一份。然后下载了重装脚本准备重装系统,但是看说明现在不能让脚本自己查找系统镜像安装了,不过没关系,前段时间我下了一份Windows 10的镜像,接下来我只需要在镜像所在目录执行

python3 -m http.server

开启一个文件服务器,然后在虚拟机中执行

bash reinstall.sh windows --image-name "Windows 10 Pro" --iso "http://192.168.64.1:8000/windows.iso"

就可以了,执行后重启就可以在UTM的虚拟机界面中看到脚本执行的一系列操作。在这期间都很顺利,然而在它执行完之后,虚拟机的屏幕就黑了,而且重启也没有任何变化,看来是实验失败了?不过也可能是因为苹果整的虚拟显示器在Windows中识别不出来,所以显示不出东西,因为我看活动监视器中CPU的占用率也在跳变,虚拟机应该仍然在运行,于是我下载了Windows App(以前的远程桌面),使用虚拟机之前的IP进行连接,结果连接成功了😆。看来苹果的虚拟化框架是能运行Windows的嘛,居然没有一个人尝试一下。
不过屏幕不能亮是真的没有驱动吗?我看了眼设备管理器,搜了一下那个没有安装驱动的视频控制器的设备ID“1af4:1050”,好像是Virtio GPU,这个驱动我记得在virtio-win里是有的,而且重装脚本也会自动下载这个驱动,为什么会没有自动安装呢?可能是设备ID和驱动不一致吧……不过不影响,我选择更新驱动,在列表中选择“Red Hat VirtIO GPU DOD controller”之后UTM的虚拟屏幕中就可以看到画面了,虽然分辨率只能是1024*768……不过能用就很不错了。
再接下来我就需要验证一下它的性能是不是最好的,我把这个虚拟机的硬盘复制了一份,新建了一个使用HVF后端的QEMU虚拟机,把这个硬盘挂载上,然后使用国际象棋跑分,看了一下VZ的跑分相比HVF的跑分高了大概5%-10%,还是挺厉害的。
至于其他方面,我看了一眼用HVF的QEMU虚拟机CPU不能显示正确的型号,而VZ是可以的,另外VZ的‌SMBIOS信息中也可以看到Apple的字样,证明这个Windows确确实实是跑在了苹果的虚拟化框架。不过以上的测试都是基于x86架构的macOS,等回头我的Mac Studio到了之后再在ARM架构的macOS上再测一下,看看能不能用相同的方式安装,如果可以的话,说明VZ的虚拟机没什么兼容性的问题,UTM应该放开使用VZ安装Windows的选项,让我们测测苹果的技术才对。

在macOS 12中的UTM使用苹果虚拟化框架安装Linux

虽然在刚刚的测试中,用VZ安装Linux就和其他普通的虚拟机安装Linux一样简单,但是之前的测试是在macOS 15上测的。现在我遇到了一个新问题,我现在有一台2016年的Mac,上面运行着macOS 12,而且不能用OCLP升级到macOS 15(因为不是我的电脑)。现在我想在这台电脑上用苹果虚拟化框架安装Linux,虽然用QEMU更简单,但是感觉没意思。在macOS 12中不支持UEFI bootloader,所以我需要手工准备内核镜像之类的东西。
当然从零开始有点难,我打算先用QEMU安装一遍Ubuntu Server。在创建虚拟机之后需要注意,要把刚创建好的虚拟机的硬盘删掉,因为那是qcow2格式的,在VZ中只支持img格式的硬盘,所以删掉之后需要创建一个“RAW映像”,然后按照正常的方式安装系统。
安装好之后从“/boot”目录中把“vmlinuz”和“initrd.img”复制出来,作为Linux内核和初始Ramdisk,我看说明上要未经压缩的Linux内核映像,但是好像是压缩的也能用🤔。随后关机把在QEMU中的硬盘映像复制出来,作为根文件系统映像。
至于启动参数,可以看“/boot/grub/grub.cfg”中内核后面跟的那串,然后再加上“console=hvc0”,因为macOS 12中使用VZ没有虚拟屏幕,只能用虚拟串口连接。在一切准备好之后就可以开机了,在一串内核信息不停滚动后,显示出了登录的提示符,实验就成功结束了。
不过这样启动的话在系统中所有对内核以及对initramfs的更新就全都不会生效了,毕竟虚拟机根本读不到内核了……这倒是影响不大,反正不更新也不是不能用,更何况macOS都不打算更新,虚拟机不更新又能怎样呢🤣。

感想

看来苹果的“不支持”不代表真的不支持,想想既然是虚拟机,当然就不应该限制系统类型啊,毕竟虚拟机虚拟的是硬件,又不是软件。不过倒是也能理解苹果不需要声明支持自己的竞品,所以也没必要做相应的兼容和测试,但居然没见到有人尝试一下,也挺奇怪,明明用Mac的人也有不少对技术很有探索精神的人啊……
不过随着macOS的更新,像这些非官方支持的办法估计也很有可能出问题,毕竟苹果并不对这些情况进行任何形式的保障,也许以后苹果的哪次更新这个方法就用不了了呢……

关于HiFi的尝试与探索

2025-03-22 00:00:00

如何才能听到最原始的音乐呢?

起因

前段时间,有人在QQ群中送网易云音乐的7天体验VIP,于是随手领了一份。有了VIP之后除了可以下载仅限VIP的音乐以外,还可以选择更好的音质。我现在用的是MacBook Pro,据说在笔记本中音响效果是最好的,那么我为了能对得起这优秀的音响,也不该听垃圾音质的音乐,所以就来探索一下如何听到HiFi的音乐吧。

获得音乐

下载音乐很简单,直接下一个网易云音乐客户端就可以,不过需要注意要在设置中修改下载音质,默认选项不是最高音质。另外它这个VIP还不是最高的,再往上还有SVIP,可以听所谓的“超清母带”的音质,我不太清楚这个无损以上的那些音质到底是什么东西,也不可能为了这点东西给网易云充钱,所以我就选了个“高清臻音”的选项。
当我在下载一些免费歌曲的时候,下载到的文件是flac格式,看起来应该是没什么问题。但是下载VIP独享音乐的时候,正在下载时是flac格式,可是下载完就变成ncm格式了……虽然我知道有一些解密这些格式的软件(GitHub上有,不过好多都被DMCA takedown了,虽然也能搜到一些……),不过我还是比较好奇这个过程,既然它下载时是flac,那我在它刚下载完要变成ncm之前把网易云音乐强制结束掉不就可以获得完整的flac文件了嘛。试了一下还真可以,也就是说这个ncm加密的过程是在客户端完成的,而不是在服务器上,这还真是有点离谱……我用这个方法下载了几首喜欢听的歌,试了一下都能正常播放。不过用这个办法下载的音乐在客户端的下载中看不到,所以就没有歌词之类的东西了。

分析音乐

虽然说下载下来的文件是flac格式,但是不代表这就是无损的音乐。毕竟从网易云音乐的“无损”以上的选项都是flac的,那到底它这个无损是真无损吗?首先我在网上搜了一下,网易云音乐的黑历史很多,有些人在网易云音乐上上传了mp3的音乐,结果也有无损的选项。也就是说它这个flac很有可能是直接用mp3转换格式过来的。那这样我就不愿意了,我可以接受下不到无损,但是不能接受本来是mp3格式然后转成flac结果文件体积大增,给我的硬盘塞一堆没用的数据,所以现在我需要证明刚刚下载的音乐不是一堆没用的垃圾。
我看有人说可以使用spek查看时频谱来验证,如果是直接用mp3格式转换的flac文件会被整齐的砍一刀,因为mp3格式支持的最大采样率是48kHz,而根据香农采样定理,采样频率应该大于等于模拟信号频谱中最高频率的2倍,那么mp3支持的最高频率就是24kHz,所以用mp3转换出来的flac一般会在24kHz那里切一刀,更有甚者,如果是44.1kHz采样率的mp3就会在22kHz左右的位置切一刀。不过理论上人类的听力上限就是20kHz,更高的频率理论上人类应该是听不到。但毕竟我们追求的是HiFi,和人类能不能听到没有关系,要保证的是完整的复刻所有的信息。
于是我在我的Mac上用brew安装了spek,安装好之后直接执行spek+音乐文件的位置就可以了,我看了一下刚刚从网易云上下载的音乐,全都是96kHz采样率的音乐,而且没有被切过的痕迹。那这样就能证明网易云音乐就是真无损了吗?其实我也不知道,因为我没有从发行商直接获得的原始文件,一般要对比原始文件才知道是不是无损的……不过我在网上看说无论是“高清臻音”还是“超清母带”无一例外全都是用AI升频制作的,所以看时频谱已经没有意义了……但是我又没有证伪的方法,那就只能先凑合听喽~

播放音乐

既然音乐已经下好了,那么我直接用我的MacBook Pro播放的音乐它够HiFi吗?虽然我能听出mp3中128kbps和320kbps的区别,但是再高的我也听不出来……不过HiFi要的不是人能不能听出来,而是它发出的声音是不是完美还原。这要怎么证明呢?虽然我没有办法听出来,但如果有可视化的分析至少能看出来,于是我在手机上下载了一款“声音分析仪”软件,它可以用FFT算法分析手机话筒收集到频谱然后展现出来。只是可视化之后……我也很难看出来它够不够HiFi啊,当然理论上如果能保证播放音乐的音响和收听音乐的话筒都是最好的,那么两边的频谱应该是一样的,但是现实中还有底噪的存在,不可能完全一样……虽然如此,但我在看频谱的时候发现,播放的音乐最高频率似乎只有20kHz,我已经测过手机的话筒是能接收到更高的频率的,既然MacBook Pro的音响是最好的,怎么会只能播放20kHz的声音呢?而且它这个20kHz很明显有一刀切的感觉,应该是哪里配置错了。
于是我搜了一下,Mac默认输出的声音貌似只有44100Hz的采样率,需要在“音频MIDI设置”中将扬声器输出的格式改成更高的才能播放更高的频率。不过这也挺奇怪的,44.1kHz的最高频率是22kHz啊,为什么会在20kHz那里砍一刀呢?看香农采样定理所说的是大于等于,也许就是这个原因吧?既然我的音乐都是96kHz采样率的音乐,那么我就应该把这里的设置改成一样的。改完之后又测试了一下,发现确实是突破了20kHz,但好像没有超过22kHz,不过至少没有“砍一刀”的痕迹了,也许是音乐本身就是这样,或者是扬声器最高只能到这个水平了吧。其实我也没有那么追求HiFi,能到这样我已经很满意了。

感想

虽然对人来说也许听HiFi并不能听出来什么,但是追求HiFi还是挺有意思的,毕竟提高还原程度是可以通过可视化的方式看到的,既然如此,那就是有追求的价值。看不见的东西是玄学,可以不去追求,但是HiFi是实实在在存在的,这样也就能理解为什么会有人花大价钱去买各种昂贵的设备来提高还原度了,因为这是真的可以起到作用的啊……当然对我来说,能0成本做到尽可能的HiFi才是最重要的,花钱达到HiFi就没什么必要了🤣。

近期LLM的部署与应用经历(2)

2025-03-08 00:00:00

最近AI发展好快啊~

起因

自从上次写完文章之后,最近这段时间LLM圈又有了不少更新,感觉很值得试试看。所以这次就来看看这些新东西有什么特别的地方吧。

关于阿里QwQ模型的体验

前两天阿里的推理模型QwQ模型更新到正式版了,不过其实我也没试过他们的预览版效果怎么样……但按照他们的说法,他们的32b参数的模型水平已经相当于DeepSeek-R1 671b的模型了。如果真是这样,那就太好了,毕竟那个671b参数的模型部署难度还是相当大的,在当时想部署一个能用级别的还是挺烧钱的。但如果这个32b参数的模型能达到相同水平,那就完全没有必要买那么贵的硬件了。像上次买的RTX4090 48GiB显存魔改版可以轻松跑QwQ 32b Q8量化的版本(速度能达到23T/s),就算想跑没有量化的fp16版,也只需要再买一张RTX4090 48GiB就够了,这个成本相比DeepSeek-R1低太多了。
所以刚发布的那天我下午就把模型下载下来试了试,随便试了几个问题,答得效果确实不错,我对比了一下DeepSeek-R1,试了试“世界上最长的单词中哪个字母最多”这个问题,两边回答的格式几乎一样,都说的是“硅肺病”的英文,并且都进行了字母数量分析,主要的结论都分析正确了,但是第二多和第三多的字母数量两边说的都不完全正确。另外我还试了试DeepSeek-R1的14b和70b蒸馏版,虽然回答正确了,但是并没有分析具体字母的数量,所以从这一点来看确实是和DeepSeek-R1的水平很相似。不过后来我又让其他人试了试文本分析之类的能力,似乎没能达到他们的预期,另外我还测了测比较宽泛的问题,以及解析文本之类的问题,结果很多问题没能正确回答……所以还是不能和DeepSeek-R1相比较,不过相比DeepSeek-R1各个蒸馏版的水平还是强了不少的,至少没有出现在回答结果中随机输出英文的情况,但是偶尔会出现没有闭合标签“</think>”的情况,看起来应该不能用于生产环境……要想正经用还是得用完整版的DeepSeek-R1,但毕竟成本问题还是很大啊……所以如果需要考虑成本问题的话用QwQ还是很不错的选择。
不过QwQ相比DeepSeek-R1还有一个优势,那就是支持Agent能力,原生支持调用用户提供的函数,像它虽然解析文本的能力不怎么强,但是它可以调用工具来处理,而DeepSeek-R1要想支持就得写提示词,但是毕竟没有专门训练过,不一定能正确使用工具(虽然我没试过😝)。
另外说到Agent,好像有个叫“Manus”的产品挺火?但那个我实在没兴趣,一点技术含量都没有,还搞什么邀请码,一看就是买的水军,而且还被人不到一天时间实现了开源版OpenManus,给人笑掉大牙了🤣。

关于新出的Mac Studio的看法

搭完整版的DeepSeek-R1即使是使用上次所说的KTransformers框架也是相当费钱的,最起码也得10万CNY左右。但最近几天苹果出了新的Mac Studio,最高配的M3 Ultra可以选配512GiB的内存,可以轻松跑DeepSeek-R1 671b Q4_K的版本,然后价格最低仅需7.5万CNY。我之前还想着是出M4 Ultra呢……结果出了个M4 Max,不过新的Mac Studio出的速度比我预期的快了好多,我本来以为会在WWDC25的时候出呢……看来是想借DeepSeek-R1大卖一波,当然从这个产品来说确实应该是会大卖的,回头看看能不能搞一个来。不过现在才刚开售,还没人拿到实物呢,也没人实机跑一下,所以先等等最早买到的人跑一波看看,如果效果好的话也许能整一个呢……

关于如何查看MaxKB的完整接口文档

上一篇文章我说明了一下如何解除MaxKB用户、应用以及知识库的数量限制,后来我发现它还限制了社区版查看完整API文档的能力😅,这个限制给我看的那叫一个大开眼界,它居然还给这个文档整了个硬编码的密码,从来没见过这么搞开源的,具体就是这一行。虽然我不知道这里面提到的MD5对应的密码是多少,但是既然是开源代码,我把这句话删了不就行了……不过实际上不太行,因为它使用了Django的国际化功能,直接删掉会影响这个文件的行数,程序会报错。不过可以仔细看一下关于“init_chat_doc”这一行在密码的判断后面加了个“or True”,看来是MaxKB的开发者后来应老板要求放开“chat_doc”的限制,但是又懒得改国际化那边的东西所以加的这个吧🤣,那既然这样,我直接给“init_app_doc”对应的那句话也加个“or True”不就行了,加完之后打开“/doc/”路径,就可以看到MaxKB的完整API文档了,不需要自己手动再去抓包测试了。
至于其他的专业版功能我看了一下应该确实是需要用到XPACK包的(不过其实关于修改页面风格的前端开源了,后端在XPACK里,要想用得自己实现接口),开源的这部分最多只能到这里了,估计是这些限制没法单独搞一个包,所以他们就直接在开源代码上做限制😅,看来他们老板也是没眼力啊。
其实与其余用MaxKB,不如用Dify,至少它没有在代码里塞莫名其妙的东西来恶心人,文档也相对更完备,不过它目前还是相当的不成熟,有很多BUG,比如上传知识库显示支持Excel,但是解析的时候会失败,上传知识库如果通过改配置超过15M解析也会失败,还有它的插件很多也是不能用,比如目前阿里云的百炼会报错,退回上个版本就不支持思维链的展示等等……总之不太适合生产使用。

感想

现在的AI发展确实是快啊,才几天时间又有一堆有意思的发展,应该说现在很多公司都在趁这个机会来发布自己的产品吧,感觉现在也是一个能有很多机会的时刻,不过AI对研究能力的要求也是相当高的,想在这个时间蹭热度也得有相当厉害的能力……像阿里的水平也是相当强的,可惜营销水平不太行😆。只是像我应该也只能看着大公司的百花齐放吧,看看接下来的时间还会不会出现一些有意思的东西。

近期LLM的部署与应用经历

2025-02-22 00:00:00

玩AI开始变的有些烧钱了啊……

起因

在几年前我就已经探索并玩过很多LLM了,不过近些日子在这方面的发展似乎影响到了我的生活……由于近期某公司开发的DeepSeek在国内非常火,导致我也不得不跟上这个热潮去考虑怎么应用它。当然对于普通人来说,使用它并没有什么难度,即使DeepSeek的官方网站和APP现在基本不能用,现在各家大公司也都自行搭建了,目前我感觉使用DeepSeek体验最好的是百度,其他家使用无论是可用性还是速度都比不过百度,而且目前百度也没有限制使用量之类,还是挺不错的。
但是对我来说却不能直接使用其他公司的产品,其实要从成本来说接入其他公司的接口显然是要便宜的多,但是我需要应用的地方可能连不上那些接口😅,所以需要考虑自己搭建。

部署经历

为了能自己搭建DeepSeek,首先就得买硬件了……虽然前段时间整了台新服务器,但是让CPU来跑还是太吃力了,速度太慢了……所以为了能轻松的跑起来,最近整了张RTX4090 48GiB显存魔改版(但是手头没有空闲的机器了,只能插在一台用着i5-8400处理器的主机,这下成狗骑吕布了🤣)。有了这张显卡,跑DeepSeek-R1的蒸馏模型(从1.5B到70B的Q4_K_M量化版)倒是轻轻松松,用Ollama跑70B的模型也能到20Tps的速度。但是根据测试来看,这些蒸馏模型的效果很差,基本上没法用,这些模型经常会发生不遵守指令,内容随机掺杂英文,而且也经常发生逻辑错误,和671B的完整版完全不能比,用起来还不如Qwen2.5各规模的模型。
那怎么办呢?前几天清华大学的某个团队更新了一款叫做KTransformers的框架,据说它可以利用Intel的AMX指令集然后配一张RTX4090可以让DeepSeek-R1 671B Q4_K_M量化版跑到13Tps,能跑到这个速度那至少是可用级别了,调其他公司的接口基本上也就是这个速度,之前买的新服务器不就有这个指令集嘛(之前还感觉这个指令集有点鸡肋呢,看来还是开发度不够啊😆),如果再配一个CPU,然后把内存插满也许就可以了?可惜R760xs插不了全高的显卡,要想插全高的估计就只能买R760了,或者用PCI-E延长线?不过那样感觉不太可靠……不过之后肯定还是会想办法上完整版的模型,毕竟它的效果确实是不错,最关键的是它的市场认可度高,上了就能提高产品竞争力,所以之后应该会想办法搞到满足KTransformers的硬件然后跑起来,或者等llama.cpp合并它的算法,然后用llama.cpp会更好一些。
不过我更倾向于等Mac Studio M4 Ultra出来,应该过几个月就能出,按照目前发展趋势来看,新款Mac Studio应该会有更大的内存,理论上可以跑的动一些效果更好的动态量化版(现在能在M2 Ultra上跑的那个1.58位的效果还是不太行),相比于价格十几万的服务器,Mac Studio估计不到十万,可以说是非常有性价比了。当然如果等不及的话应该还是会选择花十几万买个有双路第四代至强可扩展处理器加512GiB内存的服务器吧……

应用经历

有了模型之后如果只是聊天那就没必要费这么大劲了,费劲搭当然是为了能让它参与到实际的工作当中。不过该如何应用它呢?首先要让它知道工作的内容,所以第一步要搞出知识库。知识库的原理倒是很简单,我之前就给我博客的聊天机器人加了RAG功能,核心就是嵌入模型和向量数据库。不过我写的那个全都是为了能使用Cloudflare的功能,脱离了Cloudflare就没用了。那如果要在本地搞应该怎么办呢?我之前用过的1Panel开发它的公司旗下有个叫MaxKB的产品看起来很不错,它使用了PGSQL和pgvector作为向量数据库来搭建知识库,而且它是用Python写的,还能用Python来写自定义功能的函数库,另外它还能用可视化的方式来设计工作流,可以轻松构建需要的逻辑,从功能上来说我还是挺满意的。
使用也挺简单,在设置里可以添加使用其他公司API的模型,也可以使用Ollama,不过这一步有个坑,Ollama并不支持设置API Key,但是它添加模型却要求配置一个API Key,文档说可以输入任意内容,我输了一个空格,可以保存,但是使用的时候会报网络错误,所以它文档里怎么不说明一下是除了空格之外的任意内容😅,浪费了我不少时间。
在添加知识库的时候可以除了内置的嵌入模型(好像是腾讯的员工搞的模型),也可以用Ollama的嵌入模型。它自带的嵌入模型用的是CPU,文档规模大的情况速度比较慢,因为在Cloudflare上我用的是BAAI的BGE模型,效果还可以,所以这次我还是选了它,但是选的是中文模型,这样就不需要再翻译了🤣。
开始我对MaxKB印象还是挺不错的,但是用着用着……在建第六个应用的时候它显示社区版只能创建五个应用😅,对于开源软件这样做限制我也是大开眼界了,要是说有些专业版功能不开源,是DLC的形式,付钱来获取更多的功能代码,我还能理解,在开源代码上做数量上的限制,这垃圾公司多少有点看不起人了😅。
那对于这种挑衅行为该怎么反制呢?它的代码倒是没有混淆之类的,还算不错,比我以前用过的KodExplorer要好,它还整个“部分开源”,有个关键文件直接是混淆过的,想改都改不了😅,至少MaxKB还能随便改。
我大概看了眼代码,只需要改两个文件就行,一个是“apps/common/util/common.py”,把其中“valid_license”函数进行判断的部分全部注释,另外一个文件是“apps/setting/serializers/valid_serializers.py”,把“ValidSerializer”方法中的“valid”方法里进行判断的部分全部注释就可以了,开源还做限制我是真的无法理解……
如果是用1Panel部署的,可以把那两个文件放到“/opt/1panel/apps/maxkb/maxkb”目录下,然后在docker-compose.yml文件的volumes段添加:

- ./common.py:/opt/maxkb/app/apps/common/util/common.py
- ./valid_serializers.py:/opt/maxkb/app/apps/setting/serializers/valid_serializers.py

就可以了。
不过总体来说从功能上我还算比较满意,就原谅它搞出这种奇葩的行为吧😆。
MaxKB主要是为了能给更多人使用,所以是网页版,部署也略显麻烦,如果是自己用呢?我之前看到过一个桌面软件,叫做Cherry Studio。它更适合开箱即用一些,功能上可能不如MaxKB强大,但是比较方便一些。比如上传文档,MaxKB需要在流程图中自行处理,这个软件会帮你处理好;添加知识库可以直接添加本地的文件夹,不用上传到服务器上;另外安装比较方便,不像MaxKB搭环境比较麻烦些,所以个人用的话可以用Cherry Studio。

感想

总的来看,DeepSeek的出现还算可以,虽然它受到的关注和它的能力也许并不匹配,但是毕竟现在的它已经是人人都能蹭的东西了,谁都能挂它的名头,我们来蹭一蹭也能分点它的好处。当然这样的结果倒也不差,开发DeepSeek的公司只能获得他们应得的部分,其他的关注度就应该被各家公司瓜分😆。我在这期间虽然很难获得什么实质性的收获,但是能在这期间能搞点很贵的硬件之类的玩玩也是不错的体验啊🤣。