Remove TypeScript

経緯

world.hey.com

DHHが「オタクくん見てる〜? 今からうちのレポジトリからTypeScriptを剥しま〜す」と宣言したことにより、Web開発者界隈でTypeScriptの是非自体の話になり騒ぎになった*1*2

github.com

その後、野次馬がたくさん集ってきてrevertプルリクエストを立てる人やTypeScript公式リポジトリから全ソースコードを消すプルリクエストを出す*3ようなキッズムーブをする人も出てきた

world.hey.com

実際の変更

8617行のTypeScriptがJavaScript化された。(Sloc 便利)

❯ scc src/               
───────────────────────────────────────────────────────────────────────────────
Language                 Files     Lines   Blanks  Comments     Code Complexity
───────────────────────────────────────────────────────────────────────────────
TypeScript                  81     10934     2048       269     8617        986
HTML                        65      1891      138         2     1751          0
JavaScript                   3       170       17        23      130         29
CSS                          2         6        0         0        6          0
SVG                          1         1        0         0        1          0
TypeScript Typings           1        13        2         1       10          1
───────────────────────────────────────────────────────────────────────────────
Total                      153     13015     2205       295    10515       1016
❯ scc src/
───────────────────────────────────────────────────────────────────────────────
Language                 Files     Lines   Blanks  Comments     Code Complexity
───────────────────────────────────────────────────────────────────────────────
JavaScript                  81     10434     1983       272     8179        752
HTML                        65      1891      138         2     1751          0
CSS                          2         6        0         0        6          0
SVG                          1         1        0         0        1          0
───────────────────────────────────────────────────────────────────────────────
Total                      149     12332     2121       274     9937        752

典型的な変更は型注釈の削除。これを全ファイルに渡って行っている。

-  respondsToEventTarget(target: EventTarget | null) {
+  respondsToEventTarget(target) {
     const element = target instanceof Element ? target : target instanceof Node ? target.parentElement : null
     return element && element.closest("turbo-frame, html") == this.element
   }

Turboとは何か

TurboはRailsのviewでSPAを書くための仕組みです。https://turbo.build/とは別。

laiso.hatenablog.com

厳密には「サーバーサイドHTMLテンプレートベースでSPAを書くための仕組み」でRails以外にも適用できるのでGitHubのorgが独立して開発されている。

github.com

背景

「静的型付け言語と動的型付け言語はどちらが良いのか」という議論は今までにも各所で行なわれてきた。TypeScriptは静的型付け言語でJavaScriptやRubyは動的型付け言語に分類される。

typescriptbook.jp

DHHは(Ruby on Railsの作者だから当然)動的型付け言語の信仰者で、TypeScriptを好んでなくて利点を認めつつもあまり熱心ではないと普段から公言していた。

Rails誕生からの十数年を経て近年は型推論で静的型付けの記述量が軽減されたり、IDEや言語サーバーが賢くなったり、世間のプロジェクトが大規模複雑化してきたりしてもその部分はブレていないようだ。

world.hey.com

なのでTurboのレポジトリがTypeScriptだったのも「ライブラリはTypeScriptにするメリットがあるんだろうな」ぐらいに自分は感じていた。

実際、37signalsが作成するRailsアプリケーションのサンプルコードはいつもデフォルトJavaScriptで、彼等のプロダクトのコードもそうなんだろうと思う。

彼にとってTypeScriptが本来なくても充分に機能する複雑な抽象レイヤーという認識だったのかもしれませんね。

laiso.hatenablog.com

あと直接TypeScript書いてたコミッタの人は2021年のCEOブチ切れ事件の時にやめてる

techcrunch.com

誰に影響があるのか

Turboのコントリビューター

RailsのviewでSPAを書いていてTurbo本体にコントリビュートしたい時にJavaScriptコードで変更をしないといけなくなる人。

一方、RailsのviewでSPAを書いているアプリケーション開発l=Turboユーザー当事者はviewテンプレートと向きあったりwebpackやesbuildを通じたアセット管理をしているだけで、Turboのインターフェイスをコードから直接呼び出すようなことはない。

なのでTurboの中身がJavaScriptになったことでアプリケーション側ではひき続きTypeScriptで書くことができる(と言ってもTurboを使っている時に主に書くのはHTMLとRubyだが)

guides.rubyonrails.org

そもそもRailsのviewを使う機会が近年のチーム開発では減ってきていてそれを指して「Railsはオワコン」とか言われていたりする。

laiso.hatenablog.com

Rails以外でTurboを使えるようにしたい人

Turboを別のフレームワークに提供するためにプラグインを書いて、その時に@hotwired/turboの型定義を参考にする人。

自分の知っている中ではLaravel版があるけど彼等もJavaScriptで書いてる。

github.com

Railsエコシステム周りでTypeScriptやっていきたい人

37signals系のライブラリがTypeScriptを剥すのは既定路線で今から覆らなさそうなので、StimulusなどのRailsでかつフロント関係あるやつが全部JS化されて生きづらくなりそう。

ニューWindowsマシンのセットアップした

10年ぶりぐらいにWindowsメイン機を構築したら色々変わっていた。その過程で情報収集しながら記録した内容をポストします。

マシンの目的

  • Windowsしか対応していないビデオゲームをプレイする
  • GPU使ったタスク。機械学習モデルの推論やファインチューニング。画像・テキスト生成AIの実行
  • Windowsデスクトップアプリケーションの開発
  • VRデバイスや3Dゲームエンジンを使った開発
  • WindowsにしかSDKがないデバイス組込ソフトウェア系の開発

やらなかったこと

日本語環境の構築

半分ぐらいサーバー機っぽいのでIMEいらんやろと思ってパスした。

WindowsはサーバーエディションじゃなくてWindows 11 Proを買った。

古いWindowsっぽく振る舞う設定系

老いに逆らってゆきたいので、基本的に差し出された最新のWindows 11環境をなるべく使うようにした。

仮想マシン内にLinux環境を作る系

LinuxベースWeb開発環境っぽいものを構築するのをやめた。デバイスやGPUを直で使いたいので仮想環境じゃない方が都合もよく、既に所持しているmacOS環境でWeb系の作業も足りているので。

.NET系のWeb環境は別で何か入れるかもしれない。

Remote Desktop

手持ちMacBookからログインして作業したいのでRemote Desktopを先に設定した。

Microsoft Remote Desktop

Microsoft Remote Desktop

  • Microsoft Corporation
  • Business
  • Free
apps.apple.com

support.microsoft.com

sshd

GUIなしでシェルでガチャガチャ作業するだけならRDP経由じゃなくてSSHでいいので以下を参考にMacからログインできるようにした。

learn.microsoft.com

以下まで実行するとログインがPowerShellになる。

learn.microsoft.com

winget

aptやbrewみたいなパッケージマネージャコマンド。ツール類をまとめて管理するために利用。

learn.microsoft.com

Git

GitHubからツールをダウンロードしてくる時などに使われがち。

公式ページにあるwingetコマンドでインストールした。

git-scm.com

Python

どうなんだろう……と思いながらMicrosoft Storeから入れた。

Stable Diffusion系の記事で3.10系にしとけみたいな記述が多かったので様子見で3.10にした。

apps.microsoft.com

Stable Diffusion web UI

ここまでセットアップした環境ですんなり起動できて、画像生成もできた。

github.com

7860ポートを開放して webui.bat --listenで起動するとネットワークの他のマシンからアクセスできる。

New-NetFirewallRule -Name 'stable-diffusion-webui' -DisplayName 'stable-diffusion-webui' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 7860

Visual Studio 2022

Windows系のアプリケーション開発に使うIDEとSDK類。

visualstudio.microsoft.com

Communityエディションでいいらしい。

Win10以降のことよく知らなかったが最新のデスクトップ向けプラットフォームはUWPというやつらしい。

learn.microsoft.com

MAUIっていうのが元Xamarinで、モバイルアプリ作るのはこれらしい。

learn.microsoft.com

PowerToys

Caps lockとcontrolどうやってスワップするんだと調べていた時に見付けた今風のやつ。

learn.microsoft.com

JoyToKey

Java版のマイクラをパッドでやる用に入れた。

joytokey.net

未だJoyToKeyが定番らしい。メンテナンスし続けてくれてありがとうございます。

Power Automate

MacでいうAutomatorっぽいやつらしい。

powerautomate.microsoft.com

マシン間のファイル送受信

Remote Desktopの接続先に接続元のディレクトリを指定できるのでファイルの受け渡しができる。

support.microsoft.com

自動ログオンとキオスク端末化

キオスク端末として普段はゲーム用に自動ログインしておき、管理者はRemoteログインするという運用をしたかったので以下を設定した。

learn.microsoft.com

Steam設定でBig Picture modeをデフォルトにしておきシステムの起動時に自動で立ち上げるようにしておくと、Xboxのコントローラーのみで操作可能な疑似キオスク端末風にできる。

help.steampowered.com

PaLM APIのファインチューニングではてな匿名ダイアリー風文章生成モデルを作る

PaLMとは

PaLMはGoogleの大規模言語モデルです。先日、日本語に対応しました。

www.itmedia.co.jp

PaLM APIのファインチューニング

PaLM APIの基本的な利用方については以下の記事が参考になります。

zenn.dev

6月頃に「PaLMって英語の受け答えにしか対応していないけど日本語でファインチューニングしたらどうなるんだろう*1」と思って実行してみたんですけど、当然のごとくエラーが出て失敗しました。

今回日本語に対応したので、再度挑戦してみました。

はてな匿名ダイアリー風文章生成モデルとは

題材として、以前以下の記事でみかけたコンセプトである「はてな匿名ダイアリー風文章生成モデル」の自作を選びました。

Anond AIは、rinna/japanese-gpt2-mediumをはてな匿名ダイアリーのデータを用いてファインチューニングし、ドメイン適応させたものです。

developer.hatenastaff.com

Quotaの申請

以下のドキュメントに沿ってすすめます。

cloud.google.com

ファインチューニングの実行はeurope-west4かus-central1でないと実行できないようになっているので、そのlocationでQuotaの申請を行います。

6月時点ではeurope-west4しか対応してなかったので、europe-west4 + restricted_image_training_tpu_v3_pod=64を申請しました。

For europe-west4, submit a request for Restricted image training TPU V3 pod cores per region in the europe-west4 region in multiples of 64.

受理までしばらく時間がかかりました(数日)。以下URLから割り当て状況を確認可能です。

https://console.cloud.google.com/iam-admin/quotas/qirs

データセットの作成

ドキュメントに従いjsonlファイルを作ります。300件ほどサンプルがあればよいかと思い、以下のような形式のデータを作成しました。

  • input_text: 投稿のタイトル
  • output_text: 投稿の本文冒頭
❯ tail dataset.jsonl
{"input_text": "表現規制派の言ってる事って「マイナスイオン」とか「水からの伝言」と何が違うの?", "output_text": "強力効果論とか限定効果論とかあるけどさ、あれってどの位証明されてどの位信用が
  けるものなの? そういう影響論を真に受けて表現規制とか公共の場に出すなとか言っているけど それが嘘だった場合(つまり、影響なんて無いか、無視できる程度だったり、他の表現や社会的に許容されて
  他の一般的行動とか慣習と同程度の影響しかなかった場合)、どうするの? 現状、その可能性は全然有る様に見えるんだけど 全然効果が無い事の為に、仕事を失ったり罵倒されり悪として扱われる人達の理
  尽な境遇を考えないなら、リベラルの名を語る資格無くね? あなた達は人を不幸にする為にリベラルとか表現規制派とかをやっているの? 違うと言うなら、何で真面目に考えようとしないの? 表現規制派の
  ってる事って「マイナスイオン」とか「水からの伝言」と何が違うの? 追記 冒頭に挙げた例が却って一例に拘泥して論点を見失う原因になるようなので、消しまし"}
{"input_text": "甲子園球児の笑顔が辛い", "output_text": "しんどい場面で笑ってるのがキツイ。本当は「くそがああああ!!!!」とブチギレたいだろうに。グローブでもベンチに投げつけたいし、バット
  し折りたいだろう。緊張極まってプルプル真っ青な顔でいたいだろうに。テレビもあるし、一生残るし常に「どんな状況でも甲子園楽しんでます!」を演出しなきゃいけないのしんどすぎるだろ。小さい頃に
  ちゃイジメられてたのにヘラヘラ笑うしか無かった自分を思い出して見てられん。はーしんど。"}
{"input_text": "お金がなくなっていくって怖いよね", "output_text": "元々貧乏な生活してささやかな貯金をするのが趣味だった。 今配偶者がなおるあてのない長く療養が必要な重い病気になって貯金を切
  崩す生活をしてて、使える制度をフルに使っても100万円しかない貯金が毎月10万円ずつ減ってるの見てるけど、配偶者が重い病気で怖いとか悲しいより、このお金が無くなるという方が正直ストレスに感じて
  。 薄情なやつだな、と思うけど、そんなことを悟られないようにして最期まで面倒みるから、許して欲しい。 実家、新築の家を昔ローンで買ってたけど、今年55歳の父親が1500万の残債がどうにもならなく
  売りに出すって。でも、私あの家にそんな価値ないって知ってる。猫が柱をがちゃがちゃにして、あらゆるところの掃除をマメにしていたわけでないから汚れが酷くて立地が酷い。だからきっとそんな値段で
  売れない。父親と母親は熟年離婚した。母親も貧乏な生活してる。父親も母親も高卒で、両親はわたしを含め"}

これによって未知のタイトルを入力したら、はてな匿名ダイアリーの投稿の書き出しを生成してくれるのを期待します。

できたらjsonlファイルをGCSにアップロードしておきます。

トレーニングJobの実行

tuning.pyを参考に実装します。

model = TextGenerationModel.from_pretrained("text-bison@001")

model.tune_model(
    training_data=training_data,
    model_display_name='text-anond',
    train_steps=12,
    tuning_job_location="europe-west4",
    tuned_model_location=location,
)

training_dataはGCSにアップロードしたデータセットのパスを指定します。例: gs://bucket-name/path/to/dataset.csv

train_stepsはファインチューニングのステップ数を指定します。データセットのサンプル数とジョブ実行locationで調整します。

If there are 240 examples in a training dataset, in europe-west4, it takes 240 / 24 = 10 steps to process the entire dataset once. In us-central1, it takes 240 / 8 = 30 steps to process the entire dataset once. The default value is 300.

tuned_model_locationはモデルが配置される場所です。トレーニングとは別のlocationが指定できます。

このスクリプトを実行するとVertex AIのパイプライン上で実行中となり状況やエラーなどを確認できます。

https://console.cloud.google.com/vertex-ai/pipelines/runs

第1回目のチューニングを実行した直後「差別的な内容など・データセットに問題あり」警告が100件程出てきて完全に題材見誤ったわーと後悔したのですが、なんとかなりました。

チューニング済みモデルで文章生成する

無事チューニングジョブが完了したら、以下のモデル一覧にチューニング済みモデルが表示されます。

https://console.cloud.google.com/vertex-ai/models

「デプロイ」→「モデルのテスト」→「Generative AI Studio」と進むとブラウザ上で応答を確認できます。

Prompt入力欄に匿名ダイアリーにありそうなタイトルを入力してみて、生成された文章を確認します。創作性を発揮してもらいたいのでモデルのtemplateは1にしておきます。

ここで残念なお知らせですが、GoogleのGenerative AI Preview Products利用規約に従い生成された文章は第三者に公開できません(なので本稿も公開情報だけに触れています)。

なので私の感想を書くだけにとどめますが——そういえばはてな匿名ダイアリーを普段読まないので正直よく分からん。

ソースコードからこのモデルを呼び出す時のコードはideation.py が参考になります。

今回のテストだとこんな感じになります。

model = TextGenerationModel.from_pretrained("text-bison@001")
model = model.get_tuned_model(f"projects/{project_id}/locations/{location}/models/{tuned_model_id}")
response = model.predict(
    """タモリさんの本名は?""",
    **parameters
)
print(f"Response from Model: {response.text}")

おまけ: gpt-3-5-turboでも同じファインチューニングしてみた

openai.com

データセットは微修正すればいけるので追加で試した。

model = "ft:gpt-3.5-turbo-0613:personal::XXXXXXX"

completion = openai.ChatCompletion.create(
    model=model,
    messages=[
        {"role": "user", "content": "まじな話をすると、N予備校のプログラミング入門コースやるのがオススメ"}
    ],
    max_tokens=255,
)

print(completion.choices[0].message['content'])
❯ python tuning_openai.py
個人的な意見で、エンジニアになりたい人、プログラミングを自己流ではなくちゃんと根底から学びたい人には超オススメというか、やらない理由を教えてくれ。1.人に教える道具としてプログラミングが使え
るようになる。言語が単なる道具になる。
2.NO②を使って試してみる、NO①で作った物からいじり方を考える
3.解説あっての練習_system.out.println()の設定 ・javaの入出力の勉強
4 プログラムのバグは悪くない、そのバグは必ず意味がある、じゃないと書けない。高校の見方しか出来ない。
5 数字コード「文字コード」を理解する
6

見比べるとこっちのがはてな匿名ダイアリーっぽい(諸説ある)。

チューニングなし

我が家のインドカレー

インドカレーは、我が家の定番料理です。母はインドの友人から学んだ本格的なレシピで作るので、香り高いスパイスと豊かな味わいが特徴です。

チューニングあり

我が家のインドカレー

インド料理を美味しく頂くのはもちろんだが、カレールウを自作することが我々日本人にとってもっとも適した消費の仕方であり、肝要である。原因は3つ考えられる。

ジョブの実行部分

import openai

resp = openai.File.create(
  file=open("dataset.jsonl", "rb"),
  purpose='fine-tune'
)

print(resp)

job = openai.FineTuningJob.create(training_file=resp.id, model="gpt-3.5-turbo")

print(job)

[アクションが必要]AWS Lambda Go 1.x ランタイム終了を時系列理解

Go 1.x ランタイムでデプロイしたLambdaがあるとこういうメールが来る。

Amazon Linux AMI のメンテナンスサポートが 2023 年 12 月 31 日に終了するのに合わせて、AWS Lambda での Go 1.x ランタイムのサポートを終了します [1]。

Lambda は、provided.al2 ランタイムを使用して Go プログラミング言語を引き続きサポートします。

provided.al2 ランタイムを使用すると、AWS Graviton2 プロセッサのサポートや、より小さなデプロイパッケージとより高速な関数呼び出しパスによる効率的な実装など、go1.x ランタイムに比べていくつかの利点があります。

詳細については、ブログ記事 [2] を参照してください。

Q:「Go対応のプライオリティが下げられたのか」

ちょっとニュアンスが違う。

Lambdaランタイム 一覧にあるとうりLambdaはarm64やAmazon Linux 2サポートが進行していて、Javaや.NET、スクリプト言語などのシステム依存の割合が比較的大きい環境のが優先されている。

Goはカスタムランタイム以前にサポートされたので専用ランタイムが存在しているが、たとえばシステム依存の少ないワンバイナリを作れるRustなども専用ランタイムはない*1

なのでより正確な文脈としてはFaaSやサーバーレスサービス全般の(Dockerに限らない)コンテナネイティブなアーキテクチャへの移行という意味になると思う。

現在はウェブアプリケーション向けのソースコードからAmazon Linuxベースのイメージを生成するApp Runnerの基盤もあるし、GoogleのCloud Functions も2nd genになってCloud Runが基盤になっている。

firebase.google.com

時系列

2017年末にAmazon Linux 2 LTS Candidateが公開。

aws.amazon.com

2018年1月にAWS LambdaのGoサポートが追加。

aws.amazon.com

2018年11月にAmazon Linux 2を使ったカスタムランタイムが公開。

aws.amazon.com

2020年1月にAmazon Linux AMI(2じゃないやつ)のサポート期間が2020年6月30日から2023年6月30日まで延長。

dev.classmethod.jp

2020年1月のBuilding enterprise applications using Amazon DynamoDB, AWS Lambda, and Go | AWS Database Blogが書かれた時点ではサンプルコードにGo 1.x ランタイムが指定されている*2

2020年6月のコミットでカスタムランタイムを指定してaws-lambda-goで書いた関数をデプロイ可能になった。

https://github.com/aws/aws-lambda-go/pull/298

2020年9月の公式ドキュメントGo の AWS Lambda デプロイパッケージ - AWS LambdaではGo 1.x ランタイムが指定されている。

2022年4月頃のドキュメント.zip ファイルアーカイブを使用して Go Lambda 関数をデプロイする - AWS Lambdaの最後にprovided.al2 ランタイムのオプションが登場。


これ以降英語ドキュメントの方の経過を見ていった方がいいのではと思ったので切り換え。

2023年1月のBuilding Lambda functions with Go - AWS LambdaではまだGo 1.x ランタイムのみが記述。

2023年6月 Building Lambda functions with Go - AWS Lambda になかった

Go is implemented differently than other managed runtimes. Because Go compiles to native code, Lambda treats Go as a custom runtime. We recommend that you use the provided.al2 runtime to deploy Go functions to Lambda.

2023年8月には追加されている。

まとめ

  • Go 1.x ランタイムはAmazon Linux AMIと共にしばらく延命されていたが最近までドキュメントから流入は起きていた
  • アクションが必要

aws.amazon.com

オライリー本が買えない話その後

UPDATE: PayPalアカウントがなくてもオライリー本は買える(確信) - laiso

PayPalアカウントがないとオライリー本買えなくて不便で国がPayPal利用を遮断してしまったのでオライリージャパンの本が買えないという話をしていたのだけど現在は諦めてUSのOnline Learning with O'Reillyを購読してる。

laiso.hatenablog.com

O'Reilly Japan, Inc.の新着を毎週見てると定期的に新刊を配信してくれているみたいだしオライリージャパンには感謝している。

先のポストをした直後に『WEB+DB PRESS』 休刊のお知らせなんかもあったりして、むしろ日本語で技術書発刊してるだけでえらい! という気持ちになってしまった。

gihyo.jp

ちょっと困っているのが技術評論社のタイトルで、Gihyo Digital PublishingからDRMフリーのePubが入手できるのでそれをPlay Booksのtext-to-speechで読んでいたのがPayPal遮断によって購入できなくなってしまった。

support.google.com

Books on Google Playに電子版を配信してあればこの問題を回避できるんだけど技術評論社はなぜかKindleや他の日本のプラットフォームまでしか配信していない。

最悪紙本を通販で輸入して入手すればいいやと思いつつもオライリー本買うために一旦引越ししてPayPalをアクティベーションするかとか倒錯的なことも考えた上でとくに何もしていない感じ。

ChatGPTのCustom Instructionsはシステムメッセージに設定されるっぽい

ChatGPTのインターフェイスではなくOpenAI APIPlaygroundを使う利点として「システムメッセージを設定できる」と言っていたが、Custom instructionsによってシステムメッセージがChatGPTからも利用できるようになった。

The system message helps set the behavior of the assistant. For example, you can modify the personality of the assistant or provide specific instructions about how it should behave throughout the conversation. However note that the system message is optional and the model’s behavior without a system message is likely to be similar to using a generic message such as "You are a helpful assistant." https://platform.openai.com/docs/guides/gpt/chat-completions-api

Socratic tutor

GPT-4のSocratic tutorサンプルでは「問題の答えではなく解き方を教える」という制御をシステムメッセージで行っている。それをCustom Instructions+GPT-3.5でも試してみた。

chat.openai.com

これをCustom Instructionsではなくユーザーの会話メッセージとして入れるようにすると、答えを教えてくれる。

chat.openai.com

あなたは猿ですか?

以下はCustom Instructionsで設定した猿設定がどのように変化するのかを未設定時と比較した。Custom Instructionsの例では猿設定が維持されていたので「システムメッセージに設定される」と推測した。

chat.openai.com

chat.openai.com