分类目录归档: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. 过于“漫画化”的图片是无法识别到人脸的。

效果

樱木花道

唐太宗李世民

乾隆

韩熙载

宋太祖赵匡胤

香橙派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/

开源 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 的体验真的非常棒。

将服务器迁移到腾讯云

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

近期腾讯云做活动,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周时间,期间网站访问不了。

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

近期研究 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 使用。

Carrot Box流程管理平台

django-lb-workflow 我开发的一个Django流程引擎APP。设计之初是以使用便捷性为目标,自带了完整的模板,希望可以方便的集成到已有系统。尽管已经将django-lb-workflow做到尽量的易用,但距离真正的开箱即用还有一段距离。

Carrot Box是一个完整的Django易用,带了权限管理、部门、角色等必要模块,真正的做到开箱即用。通过对Carrot Box的定制可以方便的改造为OA、工单系统、CRM等业务系统。

Carrot Box的主要特点:

  • 是一个完整的应用,可以直接跑起来,开箱即用。
  • 自带HR模块,支持部门、角色的定义。支持按照部门、角色设置权限。
  • 带了几个范例流程,方便熟悉系统。
  • 包含一个代码生成器的使用范例,用于熟悉如果快速的创建一个自定义流程。
  • simplewf模块使用范例,以纯配置的方式添加新流程。

Carrot Box范例站点

之前的django-lb-workflow范例站点已经切换到 Carrot Box

地址: http://wf.haoluobo.com/

管理员账号:admin 密码:password

切换为其他用户: http://wf.haoluobo.com/impersonate/search

退回管理员账号: http://wf.haoluobo.com/impersonate/stop

将Carrot Box跑起来:

make init-pyenv
make init
make run

Go语言版 [Telegram Shell Bot]及Go的初体验

项目地址(Go): https://github.com/vicalloy/telegram-shell-bot-go

由于对Go不熟悉,因此之前版本的 Telegram Shell Bot 采用Python实现。在Python版发布后就开始尝试使用Go重新实现,毕竟之所以要做这东西也是想借个小程序体验一下Go语言。

我对Go语言的一些看法

随着微服务的兴起,相较以往服务的粒度可以拆分的更细。系统复杂度更多的转变为微服务构架设计的复杂度。服务拆分后每个具体的服务的复杂度将降低,系统对程序语言本身的构架能力的依赖会减少很多。同时在服务拆分后,各个服务组件可以灵活的采用适合的技术来完成工作。

Go语言本身极度精简(简陋),如果要象Java一样搭建一个单体的巨型项目会存在一定困难。Go的高性能,异步,加之足够简单,使Go在一些对性能要求较高,但业务复杂度相对较低的场合会非常适合。

Go可能永远不能变的同Java一样流行,但Go已经足够成功,值得去体验。

Go开发的相关资源

  • Tour of Go 官方的简明教程,可以快速浏览一遍了解Go的主要语言特性。代码编写过程中也可以作为参考手册。
  • Go标准类库 Go的标准类库。
  • Vim Go Vim的Go语言插件,支持语法检查、自动格式化、自动补全等特性。注:挺想试试GoLand,不过GoLand只有30天的试用期。
  • 在国内Go的官网访问不是特别方便,可以使用国内翻译的中文教程。Go标准类库(中文版) Tour of Go(中文版)

开发过程中的实际体验

Telegram Shell Bot Go 是我第一次使用Go写东西,由于只是一个小项目体验还不算特别深。Go语言中最精华的并发相关内容(goroutine / channel / select)并没有用到。

总的来说Go有着还不错的开发体验,但另一方便由于习惯了Python,Go又有不少让我用的不是特别舒服的地方。有人说Go是better C,我个人还是比较认可这个观点,相比其他语言Go很像C语言。

优点

  • Python使用缩进语法保证代码的整洁。Go则直接内置代码格式化工具来强制保证代码格式的一致性。
  • 之前听说Go的包管理很差劲。这次使用已经有go mod的支持,用下来体验还不错。
  • GC、性能好、编译速度快等。

不太习惯的地方(不一定是缺点)

  • 基础类型同Python相比差太多。Slice和Python里的List相对应,但功能方面差非常多。其中一个简单的删除对象的功能都需要自己实现。不清楚这是否是出于性能的考虑,需要让用户明确清楚相关操作的时间复杂度。但使用起来真的非常不方便。用了其他开发语言后,更让人怀念Python的列表推导。
  • Go在语法层面比较简单,相对较新的概念也就异步相关的内容(这部分Go设计的不错,实际上也并不难理解),真正难的还是适应Go的编程风格。Go的Telegram类库API风格同Python版有较大差别。我想API的风格差异更多的还是同语言本身风格差异相关的。要完全适应Go的编程风格可能需要先找几个代码写的比较好的项目先学习一下。

[Telegram Shell Bot]远程执行 Shell 命令的 Telegram 机器人

项目地址: https://github.com/vicalloy/telegram-shell-bot

很早之前就打算做这么一个东西,后来因为要调用的脚本是 Python 写的,于是直接在 Bot 里调用 Python 代码。 近期把这个想法重新实现了。

网上也有类似的项目,其中一些比较简单,甚至都没有对用户做校验,这样只要有人可以连上你的机器人就可以控制你的机器。类似的机器人里功能最强的是shell-bot。”shell-bot”模拟了一个 tty,实现较复杂,没有仔细研究。

Telegram Shell Bot目前提供的功能有:

  1. 鉴权,只有在许可列表里的用户才能对机器人发号指令。
  2. 支持命令的黑白名单。注:为避免使用 ; 跳过命令检查,类似的字符也应当加到字符串黑名单中。
  3. Shell 命令的执行,如 ls、cat、ps 等。
  4. 长时间执行命令的管理。如执行 wget 操作,只返回最开始几条输出(防止一直刷屏)。之后可以通过/tasks命令查看有哪些命令还在执行中,并可以通过 /kill pid 的方式强制结束命令。
  5. 支持 sudo。注:sudo 通过 echo password | su -S 的方式实现,需要自行评估风险。
  6. 自定义脚本放在 ./scripts 目录,通过 /script 命令可以快速访问这些脚本并执行。

django-lb-workflow 近期更新

前几天又看了一下Django的Class-based views,想着django-lb-workflow的一些设计似乎还需要优化一下,于是又去折腾了一下django-lb-workflow。

Class-based views提高了代码的复用性,但过多的Mixin和继承层次让代码变的不那么容易理解。而且在面对一些“特殊”需求时会变的有些别扭。

一个列表界面搭配一个查询表单是一个很常见的操作,但想要在Django默认的ListView里添加这个查询Form并不太容易。在ListView里通过重载get_queryset方法修改查询内容。通过重载get_context_data修改context内容。按照我的理解合理的方式应当是在get_queryset函数中创建form,在form校验成功后使用form的参数作为查询条件返回查询后的queryset。但get_queryset无法直接同get_context_data函数打交道,必须先将 self.form = form 在到get_context_data中通过self.form来获取form信息。这个过程变的非常不直观和奇怪。最终我还是选择不直接继承ListView,在自定义的ListView中重载get函数,在get函数中处理form和查询。

主要更新

  • 增加“添加会签人”的功能。只有在被加签的人处理完成后,流程才可以流转到下一节点。
  • 去掉 django-el-pagination,使用Django自带的分页功能。
  • 为简化系统使用,增加 simplewf 模块。对于只有一个事项名称和内容的流程,可以不写任何代码,只需要在系统中配置流程节点。

待解决的一些问题

做了上面一些更新后,对这个项目又开始有些倦怠了。下面的这些问题可能要等到下次再对这个项目提起兴趣的时候了。

  • 流程的查看、编辑等权限通过在settings里配置校验函数实现。事实上并不太直观,操作性上也不是特别好。更合理的方式还是将权限控制这部分也放到 Class-based views 中,可以通过Minxin灵活配置。注:Django REST framework权限部分的设计比较完善,相关代码可以直接移植过来。
  • 目前还不支持Django 3.0。Django 3.0移除了部分兼容性代码,导致系统跑不起来。
  • 文档…

换回自己的VIM配置文件

用过一段时间网上的通用VIM配置文件。使用通用配置文件本来是为了省心,实际用下来却并不省心。通用配置加载的东西是在太多,出了问题很难排查。默认配置里有部分不符合自己习惯的东西也很难改,修改之后更是衍生出一堆奇怪的问题。

最近新装了一台主机,趁着设置电脑的时候将VIM的配置重新整理了一遍,改用自己的VIM配置文件。

当前VIM下的插件管理工具已经很完善,插件的添加和更新都很方便。将自己常用的插件整理了一下,并使用vim-plug对插件进行管理。在加上少量自定义设置后,VIM的配置文件就好了。在换回自己的VIM配置后,VIM终于又重新开始变的好用了。

我的VIM设置可以在 这里 找到。