Author Archives: wencan

PyTorch模型训练经验教训之二

同上一篇,“优化”是指提高训练速度、降低训练时间 ,效果是指模型的评价指标结果。

Posted in Uncategorized | Leave a comment

PyTorch模型训练经验教训之一

本文为过去近一个月,我跑PyTorch模型训练所获得的经验和教训。 本文所述“优化”是指提高训练速度、降低训练时间 ,效果是指模型的评价指标结果。

Posted in Uncategorized | Leave a comment

宜家毕利书柜DIY安装经验和教训

商品: 工具: 选购: 安装:

Posted in Uncategorized | Leave a comment

PaddleNLP安装

PaddleNLP可能是安装体验最差的ML程序了。安装和安装过程中,你可能会遭遇一系列错误。下面挨个介绍。 说明,我的操作系统是Fedora 38和Debian 12。当前PaddleNLP最新版本为:v2.6.1,Paddle最新版本为v2.5.0。下面只包含我当前遇到过的问题。 一、libssl.so.1.1: cannot open shared object file: No such file or directory。 系统没有OpenSSL 1.1。Fedora系统,直接安装openssl1.1即可。Debian系统,需要下载OpenSSL 1.1源码,编译安装。 二、MemoryError: (ResourceExhausted) Fail to alloc memory of XXX size。 不是电脑内存不足。切换到PaddleNLP 2.4.0和Paddle 2.4.2即可。 三、实例代码执行结果与预期不符。比如对“2月8日上午北京冬奥会自由式滑雪女子大跳台决赛中中国选手谷爱凌以188.25分获得金牌!”执行information_extraction信息抽取,结果为空。 切换到PaddleNLP 2.4.0和Paddle 2.4.2即可。 四、PaddleNLP和Paddle所依赖的protobuf版本冲突。 PaddleNLP 2.4.0和Paddle 2.4.2依赖的protobuf版本不冲突。或者可以查下PaddleNLP和Paddle各个tag下requirements.txt要求的protobuf版本。 五、pip提示:ERROR: Could … Continue reading

Posted in Uncategorized | Tagged , | Leave a comment

一种从客观数据到代码实现的编程思想

这套编程思想,从我日常工作中总结得来,用于解决一些复杂业务问题。内容偏抽象,表达能力有限,不喜请绕道。 一、调研客观数据,放弃主观思考。 以往解决问题,往往基于认知和思考。认知是有限的,主观思考易产生偏见。 解决问题,就从问题本身出发,尽可能搜集问题的表现数据,找出数据特征和规律。最后,程序要的做,就是把数据的特征和规律描述出来。 二、程序是数据的处理过程。 所有程序,最顶层的抽象,都是数据的“输入 – 处理 – 输出”。如下图所示: 实现中,中间的“处理”过程,是程序的主要复杂点。“计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决”。对于复杂的处理,一个中间层不够,那就多个,于是可以得到: 在上面的模型中,每层都封装了数据。一层的数据,转换为下一层数据的过程,就是逻辑。 下面是一个虚构的商品请求程序模型: 这个商品请求程序模型,存在五层数据。第一层的数据是“商品请求数据”,通过逻辑“查询商品”,转换为第二层的数据“商品基础数据”…… 程序也可以描述为:输入数据,经过多层转换处理,最终得到输出数据的过程。 三、数据模型和关联。 数据(模型/结构)由属性/字段组成,不带操作/逻辑(逻辑被视为数据的转换过程)。每层有一到多个/块数据。单层内的数据之前可能存在关联,这种关联在代码上表示为数据间的组合。 下面是一组虚拟的用户和钱包数据模型: 上面的数据模型,如果用代码来实现,可能是下面这样的: 四、完整的可实现的程序模型。 一个程序模型示例(省略了数据模型细节): 在上面的示例模型中:存在多道程序逻辑(数据转换逻辑),模块间的边界清晰,部分数据和逻辑被复用,部分数据被复制而不是转换到下一层(实际代码中可能什么也没干)。 下面是一个虚拟的下单请求程序示例(只有一道程序逻辑): 最后要做的,就是用代码,把这个程序模型描述出来。 下面是一个真实案例的模型(省略了大量细节): 上面真实案例模型,是一个邮件发送程序,包含一个邮件发送的通用框架,这个框架支持不同业务(图中的1、2、3)的邮件。

Posted in Uncategorized | Tagged | Leave a comment

新的Go语言缓存中间件:restcache

我开发的第一套缓存中间件是cachex。cachex支持自定义存储后端,实现了哨兵机制,自带lru存储,支持系统故障时使用过期缓存数据。 cachex的主要问题是不支持批量处理。这也导致在上家公司,cachex未能上阵。我在上家三年时间一直不能开发出支持批量处理的缓存中间件,我也写了三年业务耦合的缓存处理代码。 这次的restcache是fastrest组件库的一个组件。在写restcache之前,我创建了gox项目,实现了优化版的lru,和一套完整的支持批量处理的哨兵机制,然后再实现restcache就简单多了。解决一个复杂问题的一个有效方法,就是模块拆分。 一套完整的缓存,应该包括三个模块:存储、查询、中间件。三个名字是我取的,不准确。 cachex和restcache实现的就是缓存的中间件,并定义了存储和查询的接口。restcache的用户需要自己实现存储和查询。restcache已经附带了一套lrucache存储,可以直接用。但因为用户的redis库版本会不同,restcache没有实现redis存储。 典型的缓存流程如下: 应该绝大多数缓存都是这个流程。这个流程的主要麻烦有两个: 解决方案为: restcache刚刚开发出来,虽然我写了很多单元测试,但经过项目的考验才能成为一个成熟稳定的组件。

Posted in Uncategorized | Tagged | Leave a comment

reloader:Go服务热升级支持

以前我在公司写过一个简单的Go热升级支持程序。但是工作时间写的,领导不准开源。后我想另写一个开源版本,但一直没想到解决多端口的问题。后来就慢慢忘却了。 直到最近一次偶然的机会,这个程序被人重新提起。又遇上待业期,正需要写点东西打发时间。突然灵感来了,想到了多端口的解决方案。 于是有了reloader。 思路基本是之前版本的扩展版。一个master进程,多个worker进程,一个worker进程处理一个侦听器。这样可以实现多端口的动态侦听和关闭。我又做了些进程管理的优化,推送到github。 无法否认,我的解决方案存在很多问题,因为偷偷起了多进程。比如程序在所有侦听器和连接都关闭后需要上层逻辑结束,这对于单进程无碍,对于reloader却是可能多了N个垃圾worker进程。这些问题,得等待找到更好的解决方案。

Posted in Uncategorized | Tagged | Leave a comment

重读《黔之驴》

今天计划做点无聊的事。突然想起柳宗元的《黔之驴》。原文如下: 黔無驢,有好事者,船載以入;至則無可用,放之山下。虎見之,龐然大物也,以為神。蔽林間窺之,稍出近之,憖憖然莫相知。他日,驢一鳴,虎大駭遠遁,以為且噬已也,甚恐!然往來視之,覺無異能者,益習其聲,又近出前后,終不敢搏。稍近益狎,蕩倚衝冒。驢不勝怒,蹄之。虎因喜曰:「技止此耳!」因跳踉大闞,斷其喉,盡其肉,乃去。 噫!形之龐也,類有德;聲之宏也,類有能。向不出其技,虎雖猛,疑畏卒不敢取,今若是焉,悲夫! 大意是说:黔地没有驴,一个无聊人运了头驴过去。黔地老虎没见过驴,开始很害怕,后发现驴不过“技止此耳”,跳上去,吃了驴。 故事创作于作者永贞革新失败之后。后人一致认为,作者是在讽刺朝中外强中干的权贵。 以我今天的眼光来看,故事却是这样的:一个很有想法的人,给一个没有驴子的地方运了头驴。驴新来,遭到当地传统势力的敌视,最终不敌,被吃了。这个很有想法的人,就是指作者自己,驴指永贞革新,老虎指当时朝中掌控实权的权贵和地方的藩镇。 我们今天谋求创新,就要做很多看似无聊的尝试,敢于承担失败的风险。想法的落地,则需要短时间适应现实情况,否则很快夭折。即使最终项目失败了,也未必意味着想法是错误的。现在黔地已经没有老虎,留下的是驴。

Posted in Uncategorised | Leave a comment

Python实现数据类的方法集合

当前Python最新稳定版为3.6。主流Linux发行版官方仓库提供Python版本的有2.7和3.5,默认依然是坚强的2.7。 1、dataclass装饰器。正规军,需要Python 3.7+,还在路上。dataclass装饰器会给类添加__init__、__str__、__repr__等方法。 @dataclass class InventoryItem: ”’Class for keeping track of an item in inventory.”’ name: str unit_price: float quantity_on_hand: int = 0 def total_cost(self) -> float: return self.unit_price * self.quantity_on_hand 2、collections.namedtuple和typing.NamedTuple。要求不多的用这两个最合适了。Python 3.6+的typing.NamedTuple才支持默认参数。 class Employee(NamedTuple): name: str id: int = … Continue reading

Posted in Uncategorised | Tagged | Leave a comment

在Linux Minecraft中输入中文——进阶:在告示牌输入中文

两年前的一篇文章,我讲到如何在Linux Minecraft中输入中文。脚本内容是转的别人的。该方法只能用于聊天,不能用于编辑告示牌。 其实只要把脚本修改下,就可以通用。只会复制粘贴,不会派生定制,做程序员的我真的不好意思。 原脚本内容为: #!/bin/bash -e chars=$(zenity –title 中文输入 –text 中文输入 –width 500 –entry 2>/dev/null) sleep 0.1 xdotool key –delay 150 Escape t sleep 0.2 xdotool type –delay 150 “$chars” xdotool key Return 其中正文第一行为弹出对话框,接收用户输入。第三行输出t键。第五行输出对话框接收的输入。第六行输出回车。很明显,第一行和第五行才是重点。其它几行不过辅助性的,帮用户偷懒。 现在只要改下: #!/bin/bash -e chars=$(zenity –title 中文输入 … Continue reading

Posted in Uncategorised | Tagged | Leave a comment