nikkie-ftnextの日記

イベントレポートや読書メモを発信

イベントレポート | オンライン開催のみんなのPython勉強会#62(若手を応援!回)にスタッフ参加しました #stapy

はじめに

頑張れば、何かがあるって、信じてる。nikkieです。
10/14の「みんなのPython勉強会」にスタッフ参加してのレポートです。

目次

勉強会の概要

みんなのPython勉強会#62 - connpass

「みんなのPython勉強会」では、Pythonを中心としてプログラミングを仕事、研究、趣味など様々なシーンに生かす方法を一緒に学びます。

今回の企画についてはスタッフのあべんべんさんがnoteにまとめています。

一部引用すると

こういった経験(※引用者注:大人数の前でのアウトプット)をできるだけ若手にも体験させたいし、ベテランも若手からいろいろ学びたいのです。

勉強会の様子

YouTube アーカイブ

Togetter

勉強会の裏側(How nikkie worked as staff)

数ヶ月前の宿題:待機中のBGM🎶

6月にお品書きスライド再生をしたところBGMの要望をいただいた1ので今回試してみました。
Zoomで画面共有するときに「コンピュータの音声を共有」を有効にします。
画面を共有 – Zoom ヘルプセンター
画面共有をしている状態で、macOSiTunesで用意していた音源を流しました。

Zoomに流れているかはチャットで聞いたところ回答があり大変ありがたかったです。
今思うと別端末でZoomに入って確認する方法もありましたね。

今回は以下の音源を使いましたが、先日Django Girlsで色々教えていただいたので他のも試してみたいです。
フリーBGM(音楽素材)無料ダウンロード|DOVA-SYNDROME

参加者が一時チャットできないトラブル😰

「今日はチャットに8888があまり流れないな」と思っていたら、面識のある参加者の方から「参加者がチャットできない」と連絡が。
ホスト・共同ホスト(=スタッフ)以外がチャットできない設定に切り替わっていたようです。 ミーティング内チャットのコントロールと無効化 – Zoom ヘルプセンター

自分が使えている機能が他の人には使えないかもと想定するのは難しいですね。
これも別端末でZoomに入れば気づけるかもしれません。
個人的には、どこかのレポートで書いたZoomの設定API向けのconfigを用意して、コードで解決したい気持ちです(フィジビリティから要検証ですが)。

とりわけ印象に残ったトーク🤩

Hakaliのお二人のトークが印象に残りました!

池内さん基調講演『持続可能なエンジニアであるための3つの心構え』

懇親会で「どうしてPythonを?」という話になり、池内さんはPyCon JPに参加してPythonコミュニティの雰囲気が面白いと感じPythonコミュニティに関わり始めたとのことでした。
ご自身の経験を踏まえての「サードプレイスとなるコミュニティ」ですね!

秦さん15分トーク『データ未経験僧侶が2ヶ月でPythonで予測モデルを作れるようになるまで』

こちらのnoteをベースにしたトークでした。

個人的に刺さったのは、『自灯明・法灯明』の話。

プログラミングも、まず自分がやりたいことを理解して、法=正しい進め方を説いてくれるブッダ的存在を見つけて頼りながら確かに歩んでいきましょう!2

秦さんはプログラミングを始めた方を念頭に話されていたと思うのですが、入門者という立場からは先に進んだプログラマ「すみません!この方向で合ってますかー」と誰かに聞きたくてもがいているんじゃないかと思いました。

私の独学のモチベーションは、失敗を繰り返さない(次にうまくやるにはどうするか)というところにあります。
誰かがうまくやっているという情報を本でもWeb記事でも登壇でも、日本語でも英語でも漁って収集しています。
これって突き詰めると「次はもっとうまくやりたくて、でも方向性には自信がなくて、『誰かこの方向で合っているか教えて下さい!』と聞きたい」ってことなのかなという気付きがありました。

ただ求めている誰かがいるとは限らない(まだ明確な答えを持っている人がいないかもしれない)ので、あの手この手で情報漁りは続きます。
知りたいという自分の灯り(自灯明)を元に暗中模索する中で、方向性を教えてくれるような情報源(法灯明)に出会うと、「自信がなかった仮説はまるっきり見当違いじゃなさそう」と安心したり、「そうか、この方向性で考えればいいのか!」とめちゃくちゃテンションが上がったりします。
直近ではPyCon Africaのいくつかのトークを聞いて経験しました!

秦さんの15分トークはプログラミング×仏教で新たな視点を得られたので、オススメです!(アーカイブをどうぞ)

積ん読資料📚

ミニトーク『回帰分析における残差の正規性 目的変数の自然対数変換』

登壇者の山下さんが参考にした資料 http://www.u.tsukuba.ac.jp/~hirai.akiyo.ft/forstudents/HP%20title/ibunka2014/20140702Ch.8.pdf

発表への補足ツイート3で知った資料。
ものすごい詳しくて必読感があります。

三森さんトーク関連、GANまわり

Slidoの質疑やZoomのチャットで見かけたのですが、GANを語る時はG(Generator), D(Discriminator), Zなど独特ですね(数式表現から来ているんですかね)。

Zoomのチャットによるとキャッチアップには以下がオススメのようです。

終わりに

10月のstapyについて、印象に残ったトークのアウトプットをしました。

11月は12日に開催です。
みんなのPython勉強会#63 - connpass

内容はまだ公開していませんが、よろしければお越しください!
懇親会のLTもお待ちしています!!
(9月から複数人LT登壇があり、4代目LT王子としては大変嬉しく思っています。接続中4LT王子誕生に期待しています)

LT補足: Stay home, but connect global Python users! #pyconhiro

はじめに

頑張れば、何かがあるって、信じてる。nikkieです。
10/10のPyCon mini Hiroshimaで、海外PyConにオンライン登壇したこの夏の学びを共有しました。
LTの制限時間5分に収め切れなかった内容を補足としてアウトプットします。

目次

PyCon mini Hiroshimaとは

PyCon mini Hiroshima 2020は、“つながろう Python”がテーマです。
3時間にぎゅぎゅっと詰め込んだオンラインカンファレンスとして開催されました。

その歴史は古く、2015年から開催されています(2017年を除く)。

この夏オンライン登壇して各地のPython使いとつながったというLTネタが浮かび、登壇しました。

LT: Stay home, but connect global Python users!

海外のPyConへの参加・登壇への挑戦で得られたことを共有しました。

対象者には、オンライン登壇する前の私のような方を想定しています。

  • Pythonについて日本語で登壇した経験がある(Python中級者〜熟練者)
  • 海外PyConには興味もある
  • ただし英語が不安(話す・聞くに自信がない)
  • PythonPythonパッケージのドキュメントは普段から英語でも読んでいる1

伝えたかったことは次の2点です。

  1. 英語での登壇に不安がありましたが、読む・書く・聞く・話すの「読む」を重視し、ツールを使って原稿を用意するという作戦で、不安を突破しました。
  2. 英語でオンライン登壇しての学びは、登壇して何かを伝えるのに重要なのは「熱」ということです。好きな技術への想いは、英語の準備がまだ十分にできていないと尻込みせずに、自身が熱を失わないうちに、伝えるのがオススメです。

LTには4つのことを詰め込みました。

  • なぜ海外PyConで登壇しようと思ったか
  • 英語の不安を解消するための準備
  • 英語でオンライン登壇して得たもの
  • 海外のカンファレンスに参加して得たもの

詰め込みきれなかった点を補足します。

なぜ海外PyConで登壇しようと思ったか

2020年は「US PyConにプロポーザルを通す」という"アホ"な目標を掲げています2
US PyConは狭き門なので、これはなかなか困難な(実現させるのに発想を変える必要がありそうな)目標です。
一発勝負では分が悪いことは痛感していたので、何回も勝負してプロポーザルを磨くことにしました。
プロポーザルにフィードバックをもらう機会として、各地のPyConにプロポーザルを投稿しています(今年の3月〜5月のことです)。

英語の不安を解消するための準備

英語のドキュメントは(辞書を使いながら)読みますが、書く・聞く・話すには不安がある身です。

「書く」不安の解消

原稿を用意するには「書く」必要があります。
ここはツール(DeepLGrammarly)の力を使い3日本語を書き、英語は読んで整えるという方法で英語を直接書かずに取り組みました。

  1. 日本語で原稿を用意(文や段落単位)
  2. DeepLで翻訳
  3. 翻訳を読んで、単語を置き換えたり、語順を変えたり修正(訳がいまいちだったら1に戻る)
  4. DeepLの訳をまとめてGrammarlyに投入。文法ミスを直す

単語を調べるときは、macOS辞書.app4が非常に便利です。
英和も和英も1つのアプリで使えて助かっています。

登壇中、別チャンネルで「5 min left」などタイムキープの英語音声が聞こえることがありました。
タイムキープが来ると知っていても私は結構驚くので、原稿があってよかったです。
突然の英語で頭が真っ白になりながらも、目の前の原稿読み上げに集中して、話し続けていました。

「話す」不安の解消

ジャパニーズイングリッシュでなまっている自覚はあります。
去年Singaporeに行った経験5から、なまった発音でも伝わると知っていたので、ジャパニーズイングリッシュを堂々と貫くことにしました6

今回は時間が割けずにやりませんでしたが、macOSsayコマンドで練習というアイデアもあります。

「聞く」不安

今回はほとんど対策しませんでした。
オンライン登壇ということでテキストチャットでの反応や質疑が多かったです。
また、聞き取れなくても「チャットでお願いします」でなんとかなるだろうと考えていました。

過去に海外PyConに行ったときはOtterというアプリを使いました7

英語の「読み」の重要性

この夏の経験から、英語が読めることの重要性を痛感しました。

技術の進歩はめざましく、翻訳ツールを使えば、英語は一応書ける時代です。
ですが、英語が読めないとそのツールに使われてしまうと感じています。
逆に言えば「読め」さえすれば、私の例のように、「書く」「聞く」はツールを味方にできます
「正確に読むための努力は今後もしていきたいな」と思っています8

英語でオンライン登壇して得たもの

不安のあった自分の英語でも届いた!」という感覚を得ました!
他の方の登壇と比べて質疑やリアクションが少ないかもしれません。
ですが、「反応いただけた方たちには届いたんだ!」と達成感を感じています。

では、届いた要因はなにかですが、「この技術について伝えたいことがある」「Pythonでこんなことをやっていることを伝えたい」というだと思っています。
「海外カンファレンスでの登壇に興味がある。でも、英語が十分に話せないから躊躇してしまう」という方には、 ぜひ自分のに任せて、ツールの力を借りてやってみることをオススメします。
さしずめ「英語を完璧に準備することを目指すより、まず登壇してみよう」9といったところでしょうか。

英語の間違いはコワくありません。
例えば、今回のLTのタイトルですが、「世界のPythonユーザとつながろう」だったら、「Connect with other Python users around the world」の方が正しそうです。
こういった誤りはこの夏何度も犯していると思います。
ただ結果的には伝えられたと思っているので、ちょっとした間違いは気にしないというスタンスでいいと思っています。

なお、「熱」ですが、偶然にもそーだいさんの直近のアウトプットと重なりました。

一番大事なことは情熱

そーだいなるキャリアを作った、そーだいなる登壇資料の作り方 - そーだいなるらくがき帳

海外のカンファレンスに参加して得たもの

海外PyConに参加して、2種類の新たなつながりを得ました。

  1. Pythonとのつながり
  2. 各地のコミュニティとのつながり

Pythonとのつながり

各地のPyConは、Pythonの本質的なトピックについてのトークが多かったという感想です。
PyCon JPは「Pythonでこんなことができる」というバラエティに富んでいるので、これは対照的でした。
例えばメモリ管理やPythonオブジェクト指向といった話を聞いて、Pythonとのつながりが深まったと感じています。

Pythonとのつながりを深める機会を提供してくださった何人ものPython使いは、言ってみれば「ヨーダ10のような存在です。
こういったPython使いとも(一方向ですが)つながれて、私のモチベーションは上がりました。
メルマガを購読するなど、インプットに加えています。

PythonとDocker ベストプラクティス

Best practices for production-ready Docker packaging — EuroPython 2020 Online · 23-26 July 2020

Generatorについて

Reuven M. Lerner's Profile | PyCon Africa 2020

各地のコミュニティとのつながり

特筆すべきは、私と似た取り組みをしているPython使いとも出会いました!
AlyさんはChicagoのPythonコミュニティ(ChiPy)の共同オーガナイザで、SlackBotを使ってChiPyを盛り上げています。

Aly Sivji's Profile | PyCon Africa 2020

ChiPyを知った私は、リポジトリをウォッチしたり、月例会に参加したりしています。

終わりに

PyCon mini HiroshimaのLTの補足をお届けしました。
海外に渡航が難しいStay homeな世の中ですが、海外PyConにオンライン参加したら素敵な出会いが待っていました
登壇に挑戦するもよし、登壇せずに参加するもよしだと思います。
このLTと補足資料をきっかけにお一人でも海外PyConに興味を持ち参加していただけたら嬉しいです。
各地のPyConの発表はYouTubeにあるので、探してみるのもオススメですよ!


  1. PythonパッケージはGetting startedから進もうとすると日本語訳が減っていく感じがあります。PEP(Python Enhancement Proposals)も公式の日本語訳はないと思います。そんなわけでわからない語を辞書で引き、コードをガイドにしながら読んでいます

  2. 近況報告:2020夏、登壇の夏、予定していた全公演を駆け抜けました!🎤 - nikkie-ftnextの日記

  3. Langsmithというツールを最近知りました。今後試すかもしれません ref: https://twitter.com/ttk_kuribayashi/status/1313419014891139072?s=20

  4. WEB+DB PRESS の名前付け特集で知って以来、辞書.appは愛用しています

  5. Event Report | PyCon Singapore 2019 Day1 #pyconsg - nikkie-ftnextの日記

  6. ジャパニーズイングリッシュでも気にしないと思えた要因には、Twitterで知ったエピソードがあります。C・ロナウド「なぜ笑うんだい?」日本人少年の拙いポルトガル語に笑いが漏れた会場でナイスガイな対応!この時の少年の現在が凄い・・・ | FUNDO

  7. こちらで知りました:第2回 2日目「1994年のPython」,日本から参加のポスターセッションとライトニングトーク:ヨーロッパのPythonコミュニティと交流できる3日間「EuroPython 2019」参加レポート|gihyo.jp … 技術評論社

  8. この夏読んだブログに耳が痛い助言があったのですが、そのとおりだなと思います。「英語がちゃんと読めるようになって始めて自分の専門的技術力を高めるスタート地点に立てるのです。」 ref: 社内勉強会で専門的技術力を高めるには - Yahoo! JAPAN Tech Blog

  9. 「完璧を目指すより、まず終わらせろ」(Done is better than perfect)の言い回しを意識しました

  10. SOFT SKILLS』にある言い回しです

イベントレポート | #pyhack にてArgoを触りました(MLOpsに使っていきたいなと素振り🏏しました)

はじめに

頑張れば、何かがあるって、信じてる。nikkieです。
MLOpsにやや興味があり、最近はGitHub ActionsでMLOpsという以下のブログ記事を真似しています。

ここで登場したArgoなるものが気になり、9月の Python mini Hack-a-thon で触ってみました。

目次

勉強会の概要

(第115回)Python mini Hack-a-thon(オンライン) - connpass

スプリントのゆるい版みたいな感じで各自自分でやりたいことを持ってきて、勝手に開発を進めています。

Twitterの #pyhack ハッシュタグを追うと雰囲気がつかめると思います。
集中してもくもくできて素振りが捗りました。
1日お疲れさまでした。ありがとうございました!

Argoとは

Container-native Workflow Engineを標榜するArgo。
ワークフローの各ジョブはKubernetesk8s)上で動かせます。
今日触った範囲では、コンテナをつなげてワークフローを定義し実行できるという理解です。
ワークフローの各ジョブはコンテナ化されているので、異なるプログラミング言語で書けるというのが1つのメリットなのかなと思いました(マイクロサービスっぽい!)。

k8sクラスタAWSGCPに立てるのは素振りにはちょっとお高いので、minikubeを使ってローカルで動かしました。

取り組んだこと

  • ローカル環境構築
  • Argoのexampleで概念を掴む
  • GitHub Actionsで動かしているCIワークフローをArgoで動かしてみる

先日書いたGitHub ActionsでMLOpsの記事でやっているスクリプト実行がArgoでできました!

ローカル環境構築

minikube

minikube start | minikube の手順でv1.12.3をインストール。
過去にbrewで入れたv1.9系は動かなくなっていたので、アンインストールして新しいものにしました1

minikubeコマンド自分用メモ

$ minikube start
$ minikube pause
$ minikube unpause  # pauseした後の再開
$ minikube stop

Argo

minikube startしてある状態で以下を進めます。
Quick Start - Argo Workflows - The workflow engine for Kubernetes

kubectl port-forwardすると、ブラウザからArgoを設定できます。
(こちらで操作もできるようです2が、今回はyamlを書いて進めていきました)

f:id:nikkie-ftnext:20200926203657p:plain

Argo CLI

ArgoのQuick startで案内されているCLIも入れます。
Release v2.11.0 · argoproj/argo · GitHub をもとにmacOSにインストールしました。

Argo CLIkubectlのラッパーというのがポイントでした。
argoコマンドもkubectl同様-nnamespaceが指定できます。
これを指定しないと、~/.kube/configの指定によりminikube namespaceを操作するので、ワークフローがうまく実行されませんでした。

Argoのexamplesで概念を掴む

examplesのREADMEで手厚く解説されています。

READMEの一部を写経

READMEの上から

  • Hello World!(docker/whalesayを動かす)
  • Parameters(docker/whalesayに引数を渡す)
  • Steps(順次実行、並列実行)
  • Artifacts(あるコンテナの出力を次のコンテナの入力へ)

を進めました。

Argoはk8sのカスタムリソースとして定義されているので、k8sと同様にyamlファイルを書けば済みます。
k8sは業務で触っているので、kind: Workflowを指定したyamlファイルを書くというのは、結構しっくり来ました。
どんなパラメタで、また、どうファイルマウントしてDockerイメージを動かすかyamlで書いていく感じです。

argoコマンド チートシート

※自分用まとめです

  • argo lintyamlを書いた直後に、yamlの形式に異常がないか確認するのに使います
  • argo list:ワークフローの一覧
  • argo submityamlをもとにワークフローを作成して実行(--watchを付けて実行状況を監視できます3
  • argo get:指定したワークフローの詳細が見られます
  • argo logs:指定したワークフロー全体や各ステップ(ポッド)のログが見られます
  • argo delete:指定したワークフローの削除

行き着いたコマンド順(-n argoはnamespaceの指定です)

$ argo -n argo lint argo-workflow/practice.yaml
$ argo -n argo list
$ argo -n argo submit argo-workflow/practice.yaml --watch

STEP                       TEMPLATE          PODNAME                            DURATION  MESSAGE
 ✔ artifact-passing-v6rnm  artifact-example
 ├---✔ generate-artifact   whalesay          artifact-passing-v6rnm-1548704093  5s
 └---✔ consume-artifact    print-message     artifact-passing-v6rnm-1648314195  7s

# ワークフロー全体のログを見る
$ argo -n argo logs artifact-passing-v6rnm

# ワークフローの中の generate-artifact ステップだけのログを見る
$ argo -n argo logs artifact-passing-v6rnm artifact-passing-v6rnm-1548704093

$ argo -n argo delete artifact-passing-v6rnm

GitHub Actionsで動かしているCIワークフローをArgoで動かしてみる

以下のリポジトリGitHub Actions製ワークフロー(Pythonのunittestを実行)を
bring-script-more-users/python-unittest.yml at master · ftnext/bring-script-more-users · GitHub Argoで動かしてみます。
参考にしたのはこちら。

パブリックリポジトリにて動作

以下の2ステップで実装しました4

  1. checkout:git cloneしてソースコード取得5
  2. test-unit:依存をインストールしてからユニットテストを実行
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: bringscript-ci-
spec:
  entrypoint: bringscript-ci  # templatesの中のbringscript-ciを実行する指定
  arguments:  # 引数をデフォルト値込みで設定
    parameters:
    - name: repo
      value: https://github.com/ftnext/bring-script-more-users.git
    - name: revision
      value: bringscript0.1.0

  templates:
  - name: bringscript-ci
    steps:  # 順次実行する書き方
    - - name: checkout
        template: checkout
    - - name: test-unit
        template: test-unit
        arguments:
          artifacts:  # 取得したソースコードのディレクトリをバインド
          - name: source
            from: "{{steps.checkout.outputs.artifacts.source}}"

  - name: checkout
    inputs:
      artifacts:
      - name: source
        path: /src
        git:
          repo: "{{workflow.parameters.repo}}"
          revision: "{{workflow.parameters.revision}}"
    outputs:
      artifacts:
      - name: source
        path: /src
    container:
      image: python:3.8
      command: ["/bin/sh", "-c"]
      args: ["cd /src && git status && ls -l"]

  - name: test-unit
    inputs:
      artifacts:
      - name: source
        path: /python/src/github.com/ftnext/bring-script-more-users
    container:
      image: python:3.8-slim-buster
      command: ["/bin/sh", "-c"]
      args: ["
        cd /python/src/github.com/ftnext/bring-script-more-users/bringscript &&
        python -m pip install .[dev] &&
        pytest
      "]

checkoutステップはgit pullできればいいので、Dockerイメージはpython:3.8を指定。
test-unitステップはpythonだけあればいいので、python:3.8-slim-busterを指定しています。

プライベートリポジトリの場合は?

k8sSecretsを作って、プライベートリポジトリにアクセスするための情報をワークフローから参照します。

kubectl -n argo create secret generic github-creds --from-file=ssh-private-key=<SSH秘密鍵のパス>

ssh-private-keyの部分がSecretsのキーになります。
指定していないとファイル名がキーになるという挙動でちょっとハマりました6

# ... snip ...
  - name: checkout
    inputs:
      artifacts:
      - name: source
        path: /src
        git:
          repo: "{{workflow.parameters.repo}}"
          revision: "{{workflow.parameters.revision}}"
          sshPrivateKeySecret:  # 追加
            name: github-creds  # 追加
            key: ssh-private-key  # 追加
    outputs:
      artifacts:
      - name: source
        path: /src
    container:
      image: python:3.8
      command: ["/bin/sh", "-c"]
      args: ["cd /src && git status && ls -l"]
# ... snip ...

f:id:nikkie-ftnext:20200926203642p:plain

GitHub ActionsとArgoの違い

ステップの分け方が違うことに気づきました。

GitHub Actionsは1つの環境(ランナー)で複数のステップを実行します。
そのため、依存のインストールとユニットテストの実行を別ステップに分けることができます

Argoはさまざまな環境(コンテナ)でステップを実行していきます。
そのため、依存のインストールとユニットテストの実行を分けずにPythonが使えるコンテナの中に押し込むことになりました。

次にやること

今回Argoを触り、例のGitHub ActionsでMLOpsブログの真似は先に進めそうです。
AWSGCPなどクラウド上にクラスタを作り、Argoをセットアップ、そしてGitHub ActionsからArgoを呼び出すというのを今後取り組んでみようと思います。

おまけ:Dockerまわりのコンマリ

minikubeの再設定まわりでつまづき、「もしかしてDockerのDisk image size?」と見てみました(これは見当違いでした)。
macOSのDockerは定期的にコンマリする(片付けする)しかないんですね。
Docker向けに割り当てたDiskが減るたびに暫定対応として割り当てを増やしていたのですが、Docker.rawが巨大になり、ディスクを圧迫していました。

Disk image sizeを広げていくのはアンチパターンだと考えます。
上限に達したら、sizeを減らすしかなくなり、そのときにDockerイメージが全部消えます。
大量のDockerイメージの中から消してはいけないものがないか確認するよりも、定期的にコンマリしたほうがいいなと今回体験しました。


  1. ~/.minikube~/.kube/configに残っていた古い情報のためにminikube startに失敗したようなので、これらの削除も必要でした。

  2. Private Repositories - Argo CD - Declarative GitOps CD for Kubernetes など(Argo CDというのは今回触ったArgoとは別物なのかな?)

  3. kubectl-wと違ってwatchsubmitサブコマンドだけみたいです

  4. spec.entrypointに指定したtemplateが実行されます。このtemplateの中でcheckout→test-unitと順次実行する実装です(プログラミングの関数っぽいですね)

  5. artifactのgitの指定についてはドキュメントのこのあたりにありました

  6. SSH秘密鍵パスフレーズが指定されていたためにエラーになったので、Secretsに設定する際はssh-keygenで再設定して外しました。 ref: sshの秘密鍵のパスフレーズを削除する - Qiita

GitHub ActionsでMLOpsをやりたくて、サンプルワークフローのChatOpsの仕組みを読み解きました

はじめに

頑張れば、何かがあるって、信じてる。nikkieです。
データサイエンティストとしてPythonを書く中で、徐々にMLOpsに興味が出てきました。
GitHub ActionsでMLOpsしているブログ記事を知り、「私もやりたい!」とその中のChatOpsの部分を読み解いてみました。

目次

GitHub ActionsでMLOpsの例

GitHub Blogに以下の記事があります。

ここで示されている例は、pull request上でコメントすると、GitHub Actionsのワークフローのうちコメントに対応するものが実行されるというものです。

  • pull requestに /run-full-test を含むコメントを投稿すると、Dockerイメージのビルドが走り、モデルが評価されます(結果がpull requestにコメントされます)
  • pull requestに /deploy を含むコメントを投稿すると、コメント内で指定したRun IDのモデルがデプロイされます

百聞は一見に如かず、以下も合わせてご覧ください。

私はこの例を見て、
「SlackのスラッシュコマンドのようにGitHub Actionsのワークフローを呼び出せるのかっこいい!✨
これがあったら、ブランチを切って仮説に基づく変更をプッシュするだけで試行錯誤できそう。やってみたい!🤩」
とめちゃくちゃテンション上がりました!
なお、pull requestにコマンドを入力することでワークフローを実行できるので、私はChatOpsと呼んでいます1

手元のリポジトリで再現させるまで

GitHub Action: ChatOps For Pull Requests

イシューへのコメントissue_commentドキュメント)で発火するワークフローを作ります。
このワークフローはコメントに含まれるコマンドを元に、後続のワークフローをディスパッチします。
1つのワークフローで全てをまかなっているわけではありませんでした。

ワークフローのステップには、以下のmachine-learning-apps/actions-chatops@masterを使います。

      - uses: machine-learning-apps/actions-chatops@master
        with:
          TRIGGER_PHRASE: "/test-trigger-comment"
          INDICATOR_LABEL: "test-label"
          APP_PEM: ${{ secrets.APP_PEM }}
          APP_ID: ${{ secrets.APP_ID }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

/test-trigger-commentが含まれていれば、machine-learning-apps/actions-chatops@masterが実行されます。
このActionでやることはINDICATOR_LABELラベルを当該プルリクエストに付けることです。
ラベルの付加をトリガーに後続のワークフローが実行されることで、ディスパッチが実現されます。

APP_PEM, APP_ID? → GitHub Apps

GitHubには疎いので、APP_PEM, APP_IDはピンときませんでしたが、GitHub Appsというものがあるそうです。
今回手を動かした範囲ではSlackのSlack Appと同様のものという理解です。
プルリクエストにラベルを付けるといった操作をコードから行うときに、必要な権限にアクセスできるGitHub Appを作るそうです。
それを当該リポジトリにインストールして使うという仕組みになっている2ことを今回知りました。

GitHubのヘルプページに沿ってGitHub Appを作成します。

Appには以下の権限が必要でした。

  • Read Metadata(最初から付いています)
  • Read Issue(後述)
  • Read & Write Pull Requests(ラベルを付けるため)

作ったAppを、ChatOpsをやりたいリポジトリにインストールします3
Appがアクセスする範囲を確認し、Acceptします。

ChatOpsをやりたいリポジトリにはSecretも設定します4

  • APP_PEM:生成したPrivate keys(pemファイル)の中身
  • APP_IDGitHub AppのApp ID
ChatOps For Pull Requestsの裏の仕組み

Dockerイメージが実行され、以下のPythonスクリプトが動いています。
actions-chatops/label_app.py at master · machine-learning-apps/actions-chatops · GitHub

この中でIssueを読み取っているところがあり、Read Issue権限が必要でした。

ディスパッチされるワークフロー

コマンドに応じてそれぞれのワークフローを追加します。

name: Workflow of /test-trigger-comment Command
on:
  pull_request:
    types: [labeled]

jobs:
  test-trigger-comment-workflow:
    if: github.actor == 'GitHub App名[bot]'
    runs-on: ubuntu-latest
    steps:
      - run: echo 'hello World'

onで定義する発火イベントをpull requestにラベルが付いたときとしています(ドキュメント)。
これでmachine-learning-apps/actions-chatops@masterからディスパッチされます。

ifによる分岐でgithub.actor(ワークフローを実行したユーザ(ドキュメント)=pull requestにラベルを付けたユーザ)を確認します。
ラベルを付けたのがリポジトリに設定したGitHub Appだった場合に限り、stepsの部分が実行されます。

まとめ

用意するワークフローのyamlファイルは少なくとも2つ

  • コマンドに応じてディスパッチするワークフロー
    • machine-learning-apps/actions-chatops@master Actionを使う
    • GitHub Appを作成する必要あり
  • コマンドに対応して呼び出されるワークフローを1つ以上作る
    • pull requestにラベルが付いたら発火するようにする

f:id:nikkie-ftnext:20200921212900p:plain

感想

GitHub Actionsを使ったMLOpsへの一歩目を踏み出せました!
コマンドをディスパッチしてラベルを付けるという仕組みだったんですねー

動かせたのですが、「GitHubが提供する環境でモデルの訓練をするのはグレーかも」と感じています。
GitHub Actionsには使用制限があり、どんなコンピューティングにでも使えるわけではありません5
変更したスクリプトでモデルを作り、それの性能評価をするMLOps用途が、GitHub Actionsの使用制限に抵触しないと言い切る自信が私にはありません(ご存じの方いたらコメントや @ftnext まで教えてください) 。
紹介したブログでもモデルの作成などは、別の環境6で行っています。
このあたりの線引きがはっきりすれば、GitHub Actionsはデータサイエンスにも一気に広がるかもしれませんね(使用制限が今のままでも、他の環境での実行連携が驚くほど簡単にできれば、広がりそうです)

GitHub Actionsはテンプレートを触るくらいで、体系的に理解できていなかったのですが、Software Design 2020年10月号のGitHub Actions特集に助けられました。

この特集を読んだ今、machine-learning-apps/actions-chatops@masterを改造したり、ラベルを付ける汎用Action labelerリポジトリ)を使うように改造したりできるかもしれないなと思っています。

今回手を動かしたのは、今週金曜日のLTに向けてのネタ探しでもあります。
枠はまだあるようですので、興味ある方はぜひお越しください。
別の実行環境が必要という結論ですが、まだ万策尽きてないです😏


  1. 紹介したブログ記事の大元のリポジトリのワークフローのymlファイルの名前もchatops.ymlでした

  2. IIJさんのブログに詳しかったです:人に紐付かない権限で連携機能を設定できるGithub Apps | IIJ Engineers Blog

  3. インストールしたあとでGitHub Appの権限を変えた場合は、新しい権限を適用するためにConfigurationを操作する必要がありました

  4. Encrypted secrets - GitHub Docs

  5. 「アクションは次の用途には使用しないでください。(中略)gitHubアクションが使用されるリポジトリに関連するソフトウェアプロジェクトの製造、テスト、デプロイ、公開に関連しないその他の行為。」ref: GitHub追加製品の利用規約 - GitHub Docs

  6. k8s上で実行しています(まだまだ先は長いぞ。。) https://youtu.be/Ll50l3fsoYs

akiyokoさんの『現場で使える Django 管理サイトのつくり方』、Django Adminの仕組みやカスタマイズ方法に目から鱗の1冊でした #技術書典

はじめに

頑張れば、何かがあるって、信じてる。nikkieです。
技術書典9が開催中ですね!(9/22(火) 4連休最終日まで)

現場で使えるDjangoの教科書シリーズのakiyokoさんから、新刊『現場で使える Django 管理サイトのつくり方』を献本いただきました。 (ありがとうございます!)
読んだ感想をこのエントリにまとめます。

f:id:nikkie-ftnext:20200919090357j:plain

目次

『現場で使える Django 管理サイトのつくり方』とは

どんな本かはakiyokoさんのブログに詳しいです。

akiyokoさんのDjango本シリーズは毎回楽しみにしており、今回の新刊も購入予定でした。
上のエントリにあるように、まさしく「管理サイトの基本から応用に至るまでの幅広い知識が得られ、Django への理解がさらに深まる」本でした。

前提:nikkieのDjango

管理サイト2は「開発中のテストデータ投入」で主に使ってきました3
カスタマイズはできるらしい4けれど自分が使うことはあまりないだろうとすら思っていました。

読んで:落ちまくった鱗

Django Adminでできることの多さに驚きました。
「開発中のテストデータ投入」だけの利用は宝の持ち腐れでしたね。
例えば、管理サイトでパスワードリセットの機能を有効にしたり、一覧画面をダッシュボードのようにカスタマイズできたりすることを知りました(これは知ったことのごくごく一部です)。

通読して思ったことは、権限(Django Adminで操作できる範囲)を絞った上でカスタマイズすれば、特定のユーザがログインしたあとの画面としても使えそうということです。

例えば、Django Girls Blogは、はてなブログのような登録してブログを書けるWebアプリを目指していると思います。
これを実現する方法の中には、Django Adminを使うという方法もあるのでは?と思いました(経験不足のために筋が悪かったらお知らせください)。
記事を閲覧するにはユーザ登録不要です(Tutorialの実装のままになると思います)。
記事を執筆するユーザには、Postだけを操作できる権限を割り当ててDjango Adminにログインさせます(ログインや執筆機能を一から実装せずに済みます)。

同様に、プロポーザルレビューアプリもレビュアー権限のユーザをDjango Adminにログインさせていたら、一から作るより手短に済んだかもしれません。
プロポーザル投稿には一般ユーザとしてログインを必要とします(Django Girls Blogのような感じで実装する想定です)。
レビューフェーズになったら、特定のユーザにレビュアー権限を割り当てて、カスタマイズしたDjango Adminでレビュー機能を提供します。

まとめると、一部のユーザだけが可能なデータ操作は、カスタマイズしたDjango Adminの利用で実装量を減らせそうという感触を得ました。

また、これまでのシリーズ同様にコラムも充実しています。
便利なパッケージの紹介などなど、コラムからの学びも多々ありました。

Djangoは独学の身(実務では使用経験なし)からすると、akiyokoさんのコードが見られるのも学びが大きいです。
「そんなところに便利なモジュールがあるのか」「テストコードはこんな風に書くのか」などなど、akiyokoさんとペアプロしているような感覚を味わいました。

終わりに

Django Admin、何も知らなかったことを痛感する一冊でした。
仕組みやカスタマイズ方法を知った今、Django Adminで手を動かして、知ったことを知識に変えたい想いに満ちています。
カスタマイズして、Django Girls Blogの記事の一覧画面や編集画面を作ってみるというのは、素振りによさそうですね。
Django Adminのカスタマイズでできることを掴めば、それを使わない場合の実装にも活きてきそうな気がします(クラスの継承を使って設定している部分など)。

今回はインデックス作りとしてざっくり読みましたが、この本はDjango Adminを使った開発の辞書としても使えそうです。
(画面遷移図やクラス変数、メソッド一覧など、akiyokoさんのエントリの紙面サンプルを参照ください)

Djangoチュートリアルをなにか1つ終えていれば、この本から多くを得られると思います。
Django Adminを使いこなし/使い倒したい方はよろしければチェックしてみてください!

P.S. 現場で使えるDjangoの教科書も読み返したら目から鱗でした

ふと基礎編の教科書を読み返し始めたところ、「レビューアプリではこうやればもっとうまくやれていたのか!」と発見ばかりでした。
特に基礎編のビューの章、クラスベースドビューの使い方の指針はなるほどと思いました。

実は教科書は困ったときのインデックスとして使っていて、通読は後回しでした。
Djangoアプリを1つ作り上げた今、akiyokoさんの本を通読して吸収できることは非常に多くありそうです(特にコードまわり)。
なので、現場で使えるDjangoの教科書シリーズは、Djangoについて知り、手を動かした後に読み返して知識を深めるという長く付き合える本なんだと実感しました。

技術書典4から継続してDjangoについて質の高い情報をアウトプットしているakiyokoさんには感服です。
最近はDjangoの入門本が増えてきた印象ですが、akiyokoさんのDjangoの教科書シリーズは現場で使える知識が詰まっていて、私のDjango開発を引き続き支える相棒のような存在になりそうです。


  1. 先日のPyCon JP 2020で共有しています:https://pycon.jp/2020/timetable/?id=203919

  2. 私はTutorialの言葉でDjango Adminと呼ぶことが多いです

  3. 良くも悪くも以下を頑なに守ってきました:ログインページを作ろう(Django admin) · HonKit

  4. たしかモグモグDjangoDjango Admin Cookbook — Django Admin Cookbook 2.0 documentation を知りました

近況報告:2020夏、登壇の夏、予定していた全公演を駆け抜けました!🎤

f:id:nikkie-ftnext:20200914224142j:plain

はじめに

頑張れば、何かがあるって、信じてる。nikkieです。
朝晩には涼しさを感じるようになり、夏真っ盛りが過ぎたような今日このごろですね。

私はこの夏、世界各地のPyConでのオンライン登壇をやりきりました!
報告ブログを書きます。

目次

駆け抜けた全公演💃

  • 7/23 EuroPython(ネタ1)
  • 7/25 July Tech Festa(ネタ2’)※日本語
  • 8/7 PyCon Africa(ネタ2)
  • 8/28 PyCon JP(ネタ2)※日本語
  • 9/5 PyCon Taiwan(ネタ2)
  • 9/13 PyCon APAC(ネタ1)

「※日本語」の記載がないところは英語登壇への挑戦です。

7/23 EuroPython(ネタ1)

Zoom Webinar + Discord(タイムキープの音声連絡用)という構成での登壇でした。

この4連休で開催されていた pyhack 合宿で terada さんがEel + Vue.jsできれいな見た目のGUIアプリを作っていて、「JS力をつければこんなにできるんだ」と舌を巻きました。

7/25 July Tech Festa(ネタ2’)

Pythonでの自動化だけでなく、スタッフ活動の紹介もしています(なので、ネタ2' 扱いです)。

Zoom Meetingでの登壇でした。

8/7 PyCon Africa(ネタ2)

hopinというプラットフォームでの登壇でした。

8/28 PyCon JP(ネタ2)

Zoom Meetingでの登壇でした。

9/5 PyCon Taiwan(ネタ2)

Google Meet + Discord(タイムキープの音声連絡用)という構成での登壇でした。
この夏私が参加したPyConの中では、Taiwanだけが現地開催しており、そこにリモート登壇するという貴重な経験でした。

9/13 PyCon APAC(ネタ1)

EuroPythonからWorkshop仕様にアップデートしました。

Google Meetでの登壇でした。

テキストチャットの質問を拾ってインタラクティブに進めていきました。
情報量が多すぎたために1時間をオーバーしそうになり、後半は講義形式に切り替えました。
ネタ1はWorkshopの題材として可能性を感じましたし、もっとブラッシュアップできるという手応えです。

総括

昨年末、エンジニアの登壇を応援する会のLT大会で「US PyConにプロポーザルを通す」という"アホ"な目標を打ち立てていました。

3ヶ月で2ネタ6登壇という今年の夏はだいぶ"アホ"でしたね 笑
「US PyConにプロポーザルを通す」こと自体はこれからですが、海外PyConで登壇する経験をした今、達成感を感じています。
「海外のカンファレンスでアウトプットしてみる」という経験ができたことに大満足です!

この夏の登壇が100点だったというつもりは毛頭ありません。
ネタの選び方、構成やプレゼンスタイルなど試してみたい案がいくつか浮かんでいます(特に技術的な「深さ」という点が一番の課題かなと感じています)。
ですが、これらはやってみて見えたことなので、この夏登壇に明け暮れたことに後悔はなく、とても清々しい気持ちです。

6登壇は全く同内容で登壇したわけではありません。
前回のフィードバックや気づきを可能な限り取り込み、その時点での全部(できなかったことも含めて)をぶつけています。
ネタ1、ネタ2それぞれで振り返り予定です。

今感じている清々しさの要因として、PyCon JPの準備と並行してやりきったという点もあると思います。

PyCon JP 2020 コンテンツチームリーダーとしての動き方はやはりたくさん間違えました😅
トークまわりのかなりの部分を1人で動いた(そうならない選択肢が選べないほどに抱え込みすぎた)ことには反省しています。
(そんな状況でも可能な限り支えてくれたスタッフの皆さん、ありがとうございました。今年の私の動き方は持続可能という観点を著しく欠いており、今後の取り組み方を考えねばいけません)
1人で抱え込んだ大量のスタッフタスクと海外PyCon準備の両方をやり切ったのは、自分でもちょっと信じられません。

両方にコミットしていた期間(特に7月、8月)は、プライベートの時間で収まらずに有給を使うこともありました。
快く送り出してくれた同僚諸氏に感謝ですし、「応援いただいた分は仕事で返さなくては」と思っています。

わたし、頑張りましたー四月は君の嘘より)

アニメネタつながりでは、この歌詞が脳内でリフレインしています(興味ある方は、アクエリアスのCMをYouTubeで探してみてください)

君の夢が叶うのは、誰かのおかげじゃないぜ。風の強い日を選んで走ってきた

P.S. ボーナスステージ!

9/26, 27のPyCon Koreaでも登壇予定です。(公演中に採択が決まりました)
事前収録なのですでにZoomで撮り終わっているのですが、スライドの修正やリポジトリ側の更新などできることはあるので、ちょこちょこ完成度を上げていこうと思っています。

Image by Rudy and Peter Skitterians from Pixabay画像リンク

イベントレポート | オンライン開催のみんなのPython勉強会#60(マーケティング回)に(半分)スタッフ参加しました #stapy

はじめに

頑張れば、何かがあるって、信じてる。nikkieです。
8/12の「みんなのPython勉強会」の裏側と、そこで知ったある本の感想をアウトプットします。

目次

勉強会の概要

みんなのPython勉強会#60 - connpass

「みんなのPython勉強会」では、Pythonを中心としてプログラミングを仕事、研究、趣味など様々なシーンに生かす方法を一緒に学びます。

今回の主なテーマはマーケティングです。Pythonが得意とするデータ分析のニーズはビジネスやマーケティング分野で高まりを見せています。

勉強会の様子

YouTube アーカイブ

Togetter

配信の裏側:痛恨のZoom設定ミス!😫

これまでのオンライン開催では、スタッフと登壇者がZoom Meetingに集まり、参加者の方はYouTube Liveで配信を見ていました。
今回は、参加者もZoom Meetingに集まる趣向を試しました。

始まるまでお品書きスライドを自動プレゼンしながら、参加者が増えていくのを見てワクワクしていました1
100人に届く直前で本編がスタートしたのですが、直後に100人上限が設定されていることが判明😱
アーカイブ用にYouTube Live配信もあったので、そちらを案内し、100人しか参加できない状態は回避しました。
勉強会中に設定が直り、途中からは再度Zoom参加を案内しています。

Zoomの参加人数の設定は怖いですね。
懇親会では「事前リハーサルで100人入って確認できないですもんね」という話になりました。
毎回振り返りしているので、そのときにスタッフ全員で対策を考えていきます。

個人的には、「Zoomの設定がエクスポートできればいいのに」と思います。
OSCなどZoomを使ったカンファレンスではノウハウの1つとして設定値が共有されるようになりました。
例:新しいZoomミーティングの設定について紹介します - 宮原徹の日々雑感
これはありがたいことですが、退屈な手動操作が大嫌いな私は、設定をコード化したいと思わずにいられません。
人がやるのではなくコードにやらせようとすると、ブラウザ操作自動化かなあ?(設定をいじれるAPIがあるのかな?)
落ち着いたときの素振り材料の1つですね。

閑話休題:ぬいぐるみ🤗

技術者と企画力についてお話しいただいた吉政さんが、パイちゃんとソンくんのぬいぐるみ背景を公開してくださいました!

めっちゃかわいい!😍😍😍
これがあればパツパツなmtgデーも何のそのですね(シリアルなmtg中でも、顔が緩んでしまうのが悩み)

感想:『その仕事、全部やめてみよう』が面白い🤩

冒頭で阿久津さんが紹介していた1冊。
小野さんは過去の登壇者2でもあるそうです。

目次の中の「俺がやったほうが早い病」の治し方に惹かれて読み始めました3
エンジニアの先輩の言葉として、ハッとさせられるところがいくつもありました。

特に興味深かったポイント

  • 阿久津さんが紹介していた、「谷」を埋めるな、「山」を作れ!
  • チームで働くについて示唆があった、職場は「猛獣園」である

「谷」を埋めるな、「山」を作れ!

  • 谷(=弱点)は最小限カバー、山(=強み)を尖らせる
  • 周りの製品を見て谷を埋めようとすると、仕事が増える(99%の仕事は谷を埋めるもの)

例えば文書のレビューは、谷を埋めようとすると、ちょっとした単語選びや敬語などなど、めちゃくちゃ時間がかかるものです。
山があって、谷が最小限カバーされていれば、レビューはパスでいいんだと気づきました。

なぜ山を作るかというと、ユーザを喜ばせる仕事をしたいから。
時間は有限ですし、ユーザを喜ばせるのに直結する仕事が増やせるのは、やりがいがあると思います。
ユーザを喜ばせるのに直結しない仕事はまずやめることを考えてみようと思います。

脱線ですが、「ユーザを喜ばせる」を読んだ後、「ユーザを喜ばせるプロダクトって実はあまりないかも」と気づきました。
読んだ翌日、職場でチームランチがあって、menuでちょっといいランチを取り寄せたのですが、ぶかぶか容器で運んだらそうなるよねという「ウーバーイーツ系の洗礼」を浴びました。
見た目がひどいことになり、全然ちょっといいランチ感はなかった😭ので、しばらくウーバーイーツ系を使うことはないと思います。
店舗は無料で導入できるそうですが、持ち運ぶ部分は伸びしろ(工夫の余地)があるなと思いました。
ここがクリアできれば、ユーザは喜び、広く受け入れられそうです(コンビニの丼もの弁当の容器のノウハウとか使えそうじゃないですか?)

職場は「猛獣園」である

  • とがった部分(山)が異なるメンバーを重ね合わせたチーム→猛獣圏
  • エンジニア風林火山(とがりかたの4類系)
  • キレるのは高みを目指しているから

「キレる」についての考察は興味深かったです。
「高みを目指しているから」、高い理想と目の前の現実にギャップを感じているからキレる。
実は私もよくキレていて(例えば、PyCon JPスタッフ活動で、運用でカバーしようとする提案が出たときはキレてます4)、キレることに対して「よくない」と思っていたのですが、この本で捉え方が少し変わりました。
ただキレて取り繕わなかった結果、同席した方に不快な思いをさせては元も子もないので、マイルドな言い方など、追求の余地があります。

運用でカバーや複雑なもの以外には、人が生み出したわかりにくいもの、性能が悪いものにもキレます5
例えば、以下の2つの製品にはキレました。

  • dropbox:注釈機能の実装がひどすぎる
    • 注釈が増えてくるともう本当にダメです
    • 何百のレビューが付いたdezero3公開レビューでは、ブラウザがもっっっっっっさりして、レビューになりませんでした😡
  • Adobe Document Cloud:共有設定がわかりにくい
    • フォルダという概念がない(常にファイル単位で共有!?)
    • 元ファイル1に対して多の共有ファイルができる(コメントできる人を分けられるようですが、どんなユースケース想定しているんだろう?)
    • Googleドライブなどのファイル共有ツールと類似で理解できない(=わかりにくすぎ😡)
    • 日本語ドキュメントも直訳すぎて意味が取れず、怒りに拍車をかけました

終わりに

8月のstapyについて、ミスの共有と、知った本についての感想を書きました。
途中で抜けてライブで見られていない松本さんパートは後ほど見られたらと思っています。

9月は11日に開催です。
みんなのPython勉強会#61 - connpass

内容はまだ禁則事項ですが、よろしければお越しください!(なんだろう、本が積まれていますね)
懇親会のLTもお待ちしています!!


  1. 『サマー・ウォーズ』を思い出し、夏を感じていました

  2. 私がまだstapyを知らない時代ですね。歴史を感じます

  3. PyCon JPのスタッフ業で忙the殺されている現状はこれがあると思っています。この話はまた別の機会に

  4. 繰り返しますが、私は退屈な手動操作が大嫌いです。また、複雑な手順で運用でカバーするのは本当に嫌です。過去に複雑な手順にしたために、誰でもできる作業ではなくなる(属人化する)というツライ経験もしてきました。複雑は可能な限り避けて単純にを信奉しています(これも谷を埋めようとして複雑にするのではなく、単純に考えて山を尖らせると通じるかも)

  5. 書いていて思ったのですが、エンジニア3大美徳の怠惰と短気が当てはまりそうですね