作者归档:vicalloy

使用AI修复将画像还原成照片

GFPGAN 是一个使用 AI 进行人脸修复的工具,即使对非常模糊的人脸也可起到不错的修复效果。Hugging Face 提供了AI应用Demo的快速部署。我 Fork 了一份 GFPGAN 的 Demo 并做了少量的调整以加强对图片的支持。

在线体验地址 https://huggingface.co/spaces/vicalloy/GFPGAN

AI技术在图片生成领域有了不错的进展,现在已经可以通过文字生成质量不错的图片了。之前就一直想尝试用AI人脸修复将画中的人脸修复成照片,只是迫于拖延症一直未能真正动手。这些天试了一下,发现这个想法切实可行,就是修复出的效果算不上出色。

Tips

  1. AI 照片修复实际上是让 AI 对图片进行自行“脑补”的一个过程,所以原图细节一定不能过多(图片一定要小,或是),不然不利于 AI 软件的自行发挥。
  2. 樱木花道的输出效果不太好,再小丢失的细节又过多,因此加了个高斯模糊。注:理论上加高斯模糊比单纯的缩小图片效果要好,大家可以对其他图片试试。
  3. 应当是缺少样本,外加人脸检测时,如果胡子过长截取人脸时会丢失部分胡子。古人的长须无法完整修复。
  4. 过于“漫画化”的图片是无法识别到人脸的。

效果

樱木花道

唐太宗李世民

乾隆

韩熙载

宋太祖赵匡胤

新冠感染记录

过程记录

12月21日(周三)

下午的时候有些犯困,当时以为是前一天没有睡好。现在回想起来这时候可能已经感染新冠了。

12月22日(周四)

早上感觉喉咙有些痒。上班路上听广播里说喉咙痒是新冠的前兆,这时已经隐隐的有不好的预感了。下午开始零星的咳嗽,不好的预感加重,于是提前下班回家。到家后全程佩戴口罩。

由于除了喉咙有点痒以外没有其他不适,当时还认为不一定是新冠。

晚上睡觉后开始头痛外加持续的咳嗽,痛的一晚没有睡着。

12月23日(周五)

起床后体温为38.6度,持续一天都在这个温度。在床上躺了一天。由于头痛,只能干躺着,根本睡不早。抗原阳性。

早上吃了一片面包,中午一碗苗条,晚上一个苹果外加葡萄糖水。不敢多吃东西,感觉吃多了就要吐了。

由于头痛外加一直咳嗽,根本睡不着,一直没有休息好。睡前吃了一片布诺芬。晚上虽然还是一只醒,不过已经可以正常睡一段时间了。

12月24日(周六)

早上醒来后感觉好多了,体温降到了37.9,整个人舒服不少。一整天体温稳定在37.x。

出现嗅觉丧失情况。喷了很多酒精依旧闻不到酒精味。

晚上睡前鼻塞严重,不过难受程度比前两天低多了,勉强可以正常睡眠。

12月25日(周日)

早上醒来后,体温已经恢复正常,鼻塞也好了。全天除了咳嗽和流涕外没有其他不适。

嗅觉依旧未恢复。

睡前再度鼻塞。

12月26日(周一)

以外发现味觉减退的厉害。

疫苗情况

第一针和第二针疫苗针2021年7月,第三针疫苗针2022年11月(一个月前),都是科兴。理论上这段时间是疫苗保护效果最好的。

可能的感染来源

周一的时候,公司一下倒了好几个。身边的人也都陆续感染,因此本周大家都很自觉的佩戴了口罩。由于感染人数众多,公交车上一般还比较空。周二下班的时候由于公交车班次缩减的厉害(大量公交车师傅被感染了),回去的那趟公交车非常拥挤。感觉在这班公交车上被感染的概率比较大。

香橙派5(Orange pi5)初体验

前些时间心血来潮想弄个ARM单板做个微型服务器。没想到今年树莓派涨价太狠,原本¥400点4b直奔¥1000去了。刚好看到Orange pi5要发布了,据说性能提升巨大,价格¥500起。本还有些犹豫,想到树莓派都成理财产品了,于是预购享折扣。

Orange pi5 采用的是瑞芯微的 RK3588S 根据测试性能介于骁龙845/855之间。在华为推出后,这已是最强的国产ARM芯片了,比树莓派4b要强出不少。该芯片集成了 6TOPS 算力的NPU,不过瑞芯微提供的SDK最新只支持到Ubuntu20.04,因此我没有实际测试过。

Orange pi5 提供了一个 M.2 接口,不过遗憾的是没有板载 Wi-Fi ,因此只能SSD,无线网卡2选一。

由于是新出的板子,还没有官方/第三方外壳(注:现在第三方外壳已经出来了),自己用硬纸板/塑料片/尼龙立柱做了个简单的外壳。偶尔做个手工,收获满满的成就感。

自己DIY的外壳

部署的服务

初步构想是作为家庭里的微型服务器使用,跑一些不需要实时性的“高负载”的任务(已有台云主机,大多服务可以跑在云主机上)。这些天把机器的基础设施搭建了一下,更具体的用途再说了(大概率吃灰)。

为简化管理,能用 Docker 部署等服务尽量用 Docker 部署。跑的 Python 脚本用 Pipenv 创建虚拟环境。

目前部署的服务有

  • Aria2/AriaNg 下载工具,及该工具的 Web 管理界面。
  • bypy 百度云盘的下载工具。
  • File Browser 基于 Web 的文件管理器。可以方便的对设备上的文件进行管理。
  • homepage 导航页生成工具,在设备上部署的服务多了后会比较有用。

开箱视频

拿到板子后做的开箱视频: https://www.bilibili.com/video/BV198411G7oy/

使用Python做嵌入式开发

出于性能的考虑,传统的嵌入式开发都以C、C++为主。如今嵌入式设备的性能早已今非昔比,开发工具的选择方面也有了更大的自由度。对于非性能敏感的业务,Go、Python等开发语言引入的开发速度提升还是非常诱人。Python有着丰富的开发资源,在系统资源足够的情况下,Python在嵌入式环境下有着不错的开发体验。

性能

同Python高效的开发速度相对应的是Python的运行速度非常的慢,即使在脚本语言里Python也是最慢的一档。如果你的程序需要高性能,Python显然是不合适的。即使不需要高性能,也需要特别注意以保证用户体验。

使用的库尽量精简。在PC下Python的启动速度不会有明显的感觉,但在嵌入式设备下,用到的库多了后,第一个明显的感觉就是启动时间变长。如果用到的库多,启动时间甚至会超过10秒。嵌入式环境下引入一个新库需要更为谨慎,平衡好开发体验及性能影响。

程序打包(应用分发)

Python在跨平台方面做的非常优秀,大多情况下可以不需要嵌入式设备,直接本地开发调试。但程序发布的时候还需要针对应用平台就行打包。

pex会把所有的依赖和你自己的代码打包成一个.pex为后缀的可执行文件。在运行环境下直接执行该文件即可。由于开发环境的构架和运行环境的架构不一致,可以通过Docker容器就行程序的pex打包。

代码保护

对于商业项目,必要的代码保护还是有一定的必要。代码的保护可以选择下面几种方式。

  1. 编译成pyc
    • 使用命令 `python3 -m compileall -b ./;find ./ -name “*.py” -delete` 将代码编译成pyc,并删除py文件。
    • 该做法可以提供最低限度的代码保护。pyc还是可以较容易的反编译成py文件。
  2. 使用代码加密(混淆)工具对源代码进行加密。
    • 开源的代码加密工具都缺乏维护,很久未更新。如果有代码加密需求,建议使用商业工具。pyarmor
  3. 使用 CythonNuitka 等工具将代码编译成二进制文件。
    • 相比 Cython,Nuitka的使用要简单很多,建议优先使用Nuitka。需要注意的是使用 Nuitka 后内存占用率会比直接用Python解释器高大概 1/3 。
    • Nuitka的编译也可在Docker容器中进行。

Python内存泄漏原因及问题排查

Python 会自动回收内存,一般情况下不用关心内存的申请和释放问题。事实上我也一直没怎么关心过Python的内存管理问题,直到我用了 Python Prompt Toolkit 。这是一个 Python 的CLI组件库,使用简单,效果很好。只是性能用点差,另外就是它居然有内存泄漏。

内存问题产生原因

Python里内存管理主要基于引用计数实现,另外会辅以全图遍历以解决循环引用问题。一般内存问题都是对象被全局变量直接或间接持有导致。出现内存泄漏后关键是找到问题对象到底被谁给持有了。

确认内存泄漏的对象

如果一个程序内存一直异常增长,那多半是存在内存泄漏。接下来就是定位问题了。Python内存分析的工具和手段主要有下面几个:

  1. objgraph 可用现实对象的增长情况。还可以根据对象的引用关系生成图像。
    • 可以根据对象生成引用关系树以及被引用关系树。第一感觉功能很强,实际用下来效果一般。对于复杂一些的项目,生成的关系树是在太过复杂。你以为对象都是通过属性持有,实际上各类的闭包,函数指针等都会持有对象。
  2. pympler 感觉和objgraph差不多,不支持生成图像。
  3. gc.get_referents()/gc.get_referents()/gc.* 获取对象的引用计数及指向该对象的对象,以及其它分析函数。
    • 其它内存分析的库应当都是基于Python的gc模块实现。
  4. print('PromptSession count: ', len([o for o in obj if isinstance(o, PromptSession)])) 打印对象数量,确认是否被释放。

解决内存泄漏问题

要解决内存问题,关键还是找到存在内存泄漏的问题被谁给持有里,然后在需要销毁对象时释放该持有。如果想该对象持有不影响对象的生命周期(比如缓存),可以使用 weakref 库来创建弱引用。

Python Prompt Toolkit 的内存问题

出于性能等考虑 Python Prompt Toolkit 添加来大量的缓存。其中一些看似简单的缓存对象持有了其它对象的函数(函数指针),从而间接持有了其它对象,最终导致大量的对象未被释放。一般情况下一个程序只有一个 PromptSession 对象,该对象贯穿程序的整个生命周期,因此问题不容易察觉。但我的应用时一个服务端程序,需要反复创建和销毁 PromptSession 对象,问题将出现了。

我尝试用 weakref.WeakValueDictionary 改写它的缓存实现,实际过程中发现key和value都会持有对象。

目前的做法是用户断开服务器连接时进行一次缓存的清理。

开源 wiki 和知识管理系统 Outline 的快速部署脚本

项目地址: https://github.com/vicalloy/outline-docker-compose

前一段想部署一个 Wiki ,看了一圈被 Outline 的颜值吸引。Outline 支持部署到自己服务器,只是自部署的体验真的不太好。Outline 部署主要就下面几个问题。

  1. 默认使用 AWS 的 S3 服务。
  2. 不提供用户管理模块,需通过 Slack 、Google 或是自建 OIDC 服务进行登录。

网上已用基于 docker-compose 的部署方案主要有两个:

  1. outline-wiki-docker-compose
    1. 提供交互式脚本,生成 docker-compose 配置文件。
    2. 使用 Slack 进行登录,国内使用体验不好。
    3. 脚本太老,存在 Bug ,图片上传后显示不了。
  2. docker-outline
    1. 国内用户写的部署脚本。目前中文网络环境下搜索 Outline 找到的都是 soulteary 的文章。
    2. 脚本不够智能,配置参数还是有些多。
    3. 内置了 OIDC 服务,不过好像不支持用户管理,只能创建一个用户。(注:没仔细研究过,不确定)

出于自己部署的需要,参考 outline-wiki-docker-compose 的实现,新开了 Outline 的部署项目。

  1. 配置文件尽量简化。只有 config.sh 一个配置文件,其他配置文件由脚本生成。
  2. 内置 OIDC 服务,可以直接通过 Web 管理用户。

ODIC Server

项目地址:https://github.com/vicalloy/oidc-server/

多很多想自己部署 Outline 的人来说,没有本地的认证系统是一个非常头痛的问题。该Issue Local Authentication #1881 的评论数是 Outline 未关闭 Issue 中最多的。我也一度被该问题劝退。

可能 Outline 主推的还是 Cloud 版,虽然内建认证对自部署影响很大,官方依旧没有给出明确的支持方案。注:不少服务是提供OIDC认证的,如果你同时使用Gitlab,你可以使用Gitlab做OIDC认证服务器。

我最初的想法部署一个做简单的ODIC认证服务器给 Outline。出于节约内存的考虑,这个服务最好是Go或是Rust编写。找了一圈未发现合适的应用,于是回到了自己最熟悉的 Django 上。

OIDC Server 主体代码来源于 django-oidc-provider 的 example 。甚至可以说这个项目就是将 example 做了个打包。依托于 Django 优秀的插件机制和 Admin 模块,在几乎不用写代码的情况下就可以得到一个还过得去的 OIDC Server。当然缺点是内存占用量有点大,这个服务需要用掉大概100M的内存。

注:ODIC Server docker镜像使用 Github Action 进行构建。不得不说 Github Action 的体验真的非常棒。

把手机从洗衣机里抢救出来及后续

洗完澡后将手机和一堆的衣服丢进了洗衣机,等到发现的时候手机已经和衣服一起洗了20分钟。好在现在的手机防水效果做的还不错(iPhone 12mini),找到的时候手机还是亮的,除了手机上的钢化膜裂了外没有发现明显问题。

擦干后,发现下麦克风还会继续渗出水来,轻甩了几下持续出水。手机进水,网上的常规方法是将手机和大米(干燥机)放一起,让手机缓慢干燥。考虑到手机状态还可以(能正常使用),应当是手机的密封效果还不错。进去的水比较少,同时水比较难自行挥发出来,手机不知道要放多久才能用。再三考虑后决定用烤箱低温“烘培”。

将手机放入烤箱,开40°C,并开启热风循环。刚开始手机下听筒会渗出少许的水,过一段时间后外表就看不到明显的水了。在烘了1个小时后,怕高温影响电池寿命,将温度调低到38 °C ,并将烤箱定时调到6个小时(最多定时6小时),然后睡觉。

目前手机没有出现明显问题,后续如有新的情况再更新。

注:

  • 要用低温模式。如果你的烤箱不支持低温发酵,不要轻易尝试。
  • 别用微波炉。微波炉的原理和烤箱不一样,弄不好手机会炸。
  • 烘手机的时候最好把SIM卡取掉。
  • 网上看了一圈,好像没什么烤箱烘手机的先例(也没几个人把手机丢洗衣机里),不知道有没有什么潜在风险。

将服务器迁移到腾讯云

之前因为嫌备案麻烦,一直用的国外的主机。只是网站的访问速度一言难尽,毫无体验可言。

近期腾讯云做活动,1G内存3年只要¥150,简直和不要钱一样。禁不住诱惑上车了。

服务搬家

Docker

由于有了1G的“大内存”(之前只有1G内存),搬家后所有的服务都改用Docker部署。

目前服务器上跑的服务有:

  • nginx 网关,将各个子域名路由到对应服务上。
  • wordpress 我的个人博客。
    • 启用https后,css和js等静态资源始终请求的http地址,导致资源无法加载。折腾了很久都没有搞定,仔细分析后认为应当是nginx做了proxy后wordpress不知道已经换成了https,依旧生成http的资源访问地址。在nginx中增加配置 proxy_set_header X-Forwarded-Proto $scheme; 解决问题。
  • filebrowser 私人网盘。
    • 注:filebrowser,使用Go开发,部署起来比较简单。不过我不想配置systemd,为了开机自动启动功能继续使用Docker。
  • django-lb-workflow演示站点

注:可以在docker-compose.ym中将networks设置为external实现不同docker-compose之间的容器互联。由于我使用nginx作为网关,因此所有服务都使用nginxnetwork

version: "3"
services:
  filebrowser:
    image: filebrowser/filebrowser:latest
    restart: always
    ports:
      - ${IP}:10180:80
    volumes:
      - ./data:/srv
      - ./db/database.db:/database.db
    networks:
      - nginx_default
networks:
  nginx_default:
    external: true

HTTPS & DNS

之前一直使用 certbot 进行免费证书的申请,只是这东西的体验一直不是很好。这次换成了acme.shacme.sh 完全使用shell脚本编写,使用起来非常简单,按照官网文档很快就可以弄好。

之前为了改善网站的访问速度使用了 cloudflare 的CDN功能(然而速度一如既往的慢),域名服务也一并迁到了 cloudflare 。既然不再使用 cloudflare DNS的解析也迁回了国内的 DNSPOD

注:免费的HTTPS证书已经支持泛域名了,泛域名只支持DNS方式进行认证。

总结

  • 访问速度提升巨大,体验好了很多。之前连SSH都容易卡掉线。
  • 之前跑在服务器上 telegram-shell-bot 连不上服务器了,被迫停工。
  • 网站备案比预期的要简单些。备案审核需要1~2周时间,期间网站访问不了。

关于kkndme谈房产

不知道为啥,kkndme的帖子忽然出现在GitHub的热榜上,而且被冠以神贴的称号。简单的看了一下缩水版的帖子。帖子有些意思,但要说是神帖似乎有些过了。

总结

别指望房子降价,房子是中国割韭菜的主要工具,没有找到替代手段前国家不会放弃的(暂时也找不到)。别老想着买房投资。房子是给国家赚钱的,你们这些二手房就别来添乱了。

看法

kkndme文中公知味很足,文中的内容要辩证的看。11年后房价确实涨过一波,不过并不是一直在涨。10年过去了,国内外形势已经有很大的不同,房子还能不能涨还真不一定(也别指望跌)。房价重要的是要维持在一个“合理的范围内”。多少钱合理,主要看能掏钱买房的“刚需”有多少。别被打着kkndme旗号的公众号收智商税。

在线使用的图片风格迁移工具

近期研究 ONNX Runtime Web 做的一个小东西。很多代码都“借鉴”于其他开源项目,解决了图片变形等问题。

使用深度学习模型做的图片风格迁移。使用 React 和 ONNX Runtime Web 开发,推理后端用的 WebAssembly ( CPU )。根据我的测试,用 WebGL 要慢不少,而且内存占用有些夸张。

在线访问: https://vicalloy.github.io/image-transformer/

项目地址: https://github.com/vicalloy/image-transformer

Note:

  1. 所有推理工作在浏览器完成,不需要消耗服务器资源。
  2. 推理的时候需要选择图片的输出大小。不同大小的输出用的模型不同。
    • 越大的输出尺寸需要耗费的算力越多(时间越长),测试的时候可以先用小尺寸看效果。
    • fast neural style这个模型也可以支持输出任意图片大小,不过动态参数模型太大,复杂度也高,不适合 Web 使用。