• Google Colab 运行其他 Python 版本

    首先说明,这个运行其他 Python 版本并不是影响 jupyter notebook 的 Python 版本,而是在 notebook 中通过!python xxxxx.py执行我上传的脚本所使用的 Python。

    撰写本文时,Colab 的 Python 是 3.7。

    我的项目中用到了一些 3.8、3.9 的新语法,所以没法在 Colab 上面跑,但我也不想把这些语法改成旧的,所以只能在 Colab 上升级了。

    经过一番摸索,发现最靠谱的方法是在 apt 中安装新版 Python,然后全程使用 venv,而不用系统的 Python。系统的 Python 总是遇到 pip 安装库时的各种奇怪问题。

    所以,在 notebook 中的命令如下:

    !sudo apt-get update -y
    !sudo apt-get install python3.9 python3.9-distutils python3.9-venv
    
    !python3.9 --version
    
    !python3.9 -m venv venv

    之后运行 pip 安装第三方库、运行 python xxxx.py 时,都使用如下方式:

    !venv/bin/pip install xxx_library
    !venv/bin/python xxx.py
  • Kotlin 使用 protobuf 的正确方法(Maven)

    背景

    有一个后端的 Java/Kotlin 项目需要与同事的模块通信,协议是 protobuf。

    这块我想用 Kotlin 来写,当然 Java 也不是不行。没想到踩了些坑,故以本文作记录。

    文档

    protobuf 官方是有 Kotlin 的教程的,但是并不全面,这是出现各种坑的根源。

    另外,我原以为 protobuf 对 Kotlin 的专门支持是多年前就有的(指的是支持 Kotlin 的各种方便写法),然而我后来才发现是2021年才有,见 Announcing Kotlin support for protocol buffers

    方法

    1. 从 .proto 生成 .java .kt

    首先找同事得到 .proto 文件,然后下载 protoc,解压后得到一个可执行文件。

    然后按照官方教程,在命令行中执行

    protoc --java_out=$DST_DIR --kotlin_out=$DST_DIR xxxxxx.proto

    注意--java_out--kotlin_out都是需要的,当前版本的 protoc 对 Kotlin 的支持是在原来 Java 生成的基础上多了 Kotlin 的增强。

    然后就得到了一些 .java .kt 文件。

    2. Maven

    把生成的文件放进项目中,可以发现编译是不能通过的,因为缺少 protobuf 相关库。我的项目是 Maven 的,所以在 pom.xml 中加上

    <!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-kotlin -->
    <dependency>
        <groupId>com.google.protobuf</groupId>
        <artifactId>protobuf-kotlin</artifactId>
        <version>3.19.4</version>  <!-- version 要与之前 protoc 的版本对应 -->
    </dependency>
    

    这个 pom 的 artifactId (protobuf-kotlin) 是关键!!我看到的文档写的都是protobuf-java,就会导致生成的 .kt 里面的

    @kotlin.OptIn(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)

    报找不到的错误,必须使用protobuf-kotlin

    3. 使用

    这里参照 Announcing Kotlin support for protocol buffers 举的例子,用了 Kotlin 之后,写法更简洁了。假设原来 Java 的是这样写:

    DiceSeries series = DiceSeries.newBuilder()
        .addRoll(DiceRoll.newBuilder()
            .setValue(5))
        .addRoll(DiceRoll.newBuilder()
            .setValue(20)
            .setNickname("critical hit"))
        .build()

    而 Kotlin 可以改成:

    val series = diceSeries {
      rolls = listOf(
        diceRoll { value = 5 },
        diceRoll {
          value = 20
          nickname = "critical hit"
        }
      )
    }

    至于如何序列化和反序列化,继续用刚才的例子,序列化是这样的:

    series.toByteArray()

    反序列化:

    DiceSeries.parseFrom(message)
  • Google AdSense PIN 码,终于收到

    前后加起来超过5个月,终于收到了来自 AdSense 的 PIN 码。记录一下过程。

    我总共申请寄了 4 次。前面 3 次大概是 12 或 1 、2、3 月,都没有收到,当时觉得可能是疫情导致交通中断了。最后一次到了 4 月,实在没有办法,我把原来英文的地址改为中文,最后试了一次。

    终于,在 5 月底,收到了来自马来西亚(不是美国)的 AdSense 信件。

    信的地址,除了“CHINA”是英文的,其他都是中文。所以不用担心填了中文,国外的邮政看不懂,CHINA 总知道吧。我反而觉得是不是中国邮政看不懂英文(虽然基本都是拼音),所以之前一直都没有收到……

  • 在 Google 云搭建深度学习平台

    大家都知道,Google有一个很方便的 Colab ,而且到目前为止,还是免费的,并且 GPU 和 TPU 也是免费的。那为什么还要自己搞呢?因为 Colab 每个 session 只能用12小时,之后环境和数据不会保留,并且也不能进一步自定义配置和性能。Google 云给新注册的用户提供了$300 USD的赠金,非常适合学生党和个人的小项目。下面就开始体验吧。

    创建用户

    如果还没有 Google Cloud 用户,前往 Google Cloud 注册一个。这里需要一张 Visa / Mastercard 信用卡,没有的话我也帮不了你..然后$300 USD额度就到手了。

    申请 GPU 额度

    一开始的用户是没有 GPU 额度的,就算创建了带 GPU 的实例,也不能启动。请参照申请提升配额的步骤提交申请,把 GPU 的 0 改为更大的数值。在此之前,平台应该会让你把用户升级为付费账号,也就是说,如果送的额度用完了,就会从你的信用卡扣钱(注意要省着用了)。申请提升配额的页面中写可能要一两天来处理申请,但是我提交之后一小时内就批了。

    阅读更多…