May the Neural Networks be with you

ニューラルネットワークと共にあらんことを

深層学習モデルの実装を爆速にするVSCodeの設定メモ

こんにちは。@shunk031です。 新型コロナウイルスが猛威を奮っていますね。 不要不急の外出は控えるのが大切そうです。 こういう時は引きこもって論文を読むのが一番です。

今回はコードエディタであるVSCodeで、深層学習モデルの実装を爆速にするための設定についてメモします。 深層学習モデルの実装をする際にはリモート上にあるGPUを搭載したサーバで実装をしたりデバッグすることが非常に多いです。 VSCodeはこうしたリモートでのコード編集およびデバッグを簡単に行える仕組みを多数揃えています。

本記事では、深層学習モデルの実装に頻繁に利用されるPythonを対象に、以下の観点からモデルの実装を爆速にする設定や機能について紹介します:

  • Pythonの開発環境の構築
  • リモートのGPUサーバに接続するための設定
  • 深層学習モデルの実装・デバッグを簡単にする機能
  • おすすめのショートカットキー・拡張機能・カスタマイズ

私自身これまで魔改造したEmacsに引きこもってコードを書いてきましたが、以下の本でVSCodeに入門することができました。 体系的に整理されており、他のエディタから乗り換えを検討している方にオススメできる内容です。

Visual Studio Code実践ガイド —— 最新コードエディタを使い倒すテクニック

Visual Studio Code実践ガイド —— 最新コードエディタを使い倒すテクニック

  • 作者:森下 篤
  • 発売日: 2020/02/21
  • メディア: 単行本(ソフトカバー)

VSCodeのインストール

WindowsMacOSともに公式サイトからダウンロード可能です。

code.visualstudio.com

MacOSにおいて brew がインストールされている場合、以下のコマンドでインストールが可能です:

$ brew cask install visual-studio-code

コマンドパレットによるコマンドの実行

以降、簡単のためVSCodeコマンドパレットWindows: alt + shift + p , MacOS: cmd + shift + p)からコマンドを実行します。 コマンドパレットやショートカットキーに慣れるとキーボードから手を離すことなく編集が可能になります。 テキスト編集の効率化のために慣れることをおすすめします。

settings.json によるVSCodeの設定

VSCodeGUIによる設定のほか、 settings.json による設定の記述が可能です。 コマンドパレットから > Preferences: Open Settings (JSON) で設定ファイルを開くことができます。 以降では私がおすすめする設定をこの settings.json の形式で紹介します。 最終的な全体の設定は後半のセクションに示します。

Pythonの開発環境の構築

VSCodeによるPythonの開発環境はPython拡張機能をインストールすることで殆ど設定不要でリッチな補完やリファクタリング機能が使用できます。

拡張機能のインストール

Pythonの開発環境のための拡張機能をインストールします。 コマンドパレットから > View: Show Extensions を選択して検索窓から python と入力することで、以下の拡張機能を見つけることができますので、インストールしてください。

marketplace.visualstudio.com

settings.json の設定例

以下にPython拡張機能に対するsettings.jsonの設定例を示します:

{
    "python.formatting.provider": "black",
    "python.linting.pylintEnabled": false,
    "python.linting.flake8Enabled": true,
    "python.linting.flake8Args": [
        "--ignore=E501,W503"
    ],
    "python.sortImports.args": [
        "-m 3"
    ],
    "python.jediEnabled": false
}
  • black : Formatter
    • blackによるソースコードの自動フォーマットを利用します。カスタマイズ不要で規約に沿ったフォーマットに整えてくれます。
  • flake8 : Linter
    • flake8による文法チェックを利用します。
    • blackと併用する際に E501 (一行が長すぎるとエラー) *1W503 (二項演算子の前に改行すると警告) *2 を無視する設定を追加します。
    • pylintはflake8と同様に文法チェッカーとして広く用いられていますが、今回紹介する設定例ではflake8を用いるため、offにします。
  • isort : import文のソート
    • isortによるimport文の自動整理を利用します。
    • import文を改行する際のスタイルを -m 3 のように指定します。
  • jedi : コード補完
    • jediはこれまで広くPythonのコード補完に用いられてきましたが、Microsoft製のコード補完がよりリッチに動作するため、今回紹介する設定例ではoffにします。

これらのパッケージは対象のPython環境にインストールされていない場合はインストールを促すポップアップが表示されます。指示に従うことで簡単にインストールが可能です。

Python環境の指定

pyenv 等を用いた仮想のPython環境が存在する場合、コマンドパレットから> Python: Select Interpreter を選択し、Python環境の切り替えが可能です。 対象の仮想環境を選択して切り替えを行ってください。

リモートGPUサーバに接続するための設定方法

VSCodeではRemote developmentの拡張機能をインストールすることにより、ローカルでテキスト編集しているのとほとんど同様の編集が可能になります。

拡張機能のインストール

リモートのサーバ上のテキストを編集するために拡張機能をインストールします。 コマンドパレットから > View: Show Extensions を選択して検索窓から remote と入力することで、以下の拡張機能を見つけることができますので、インストールしてください。

marketplace.visualstudio.com

リモートのサーバにVSCodeで接続

コマンドパレットから > Remote-SSH: Open configuration File を選択すると、sshの設定ファイルが開きます。こちらに接続先となるサーバの情報を以下のように記入しておきます:

Host <任意の名前>
    Hostname <サーバのIPアドレス>
    User <ログインしたいサーバ上のユーザ名>
    IdentityFile <ssh鍵の場所>

サーバに接続するには、コマンドパレットから > Remote-SSH: Connect to Host を選択すると、<任意の名前> として設定したサーバ名が選択肢に現れるので選択します。 そうすると新しいウィンドウが立ち上がり、サーバに接続された状態のVSCode画面が現れます。

リモートのサーバに拡張機能をインストール

これまで複数の拡張機能をインストールしてきました。 VSCodeでは、リモートのサーバにも同様の拡張機能をインストールする必要があることに注意してください。

予めインストールすることが決まっているPython拡張機能などは、以下のようにsettings.jsonに記述することによって自動でインストールすることができます:

{
   "remote.containers.defaultExtensions": [
        "ms-python.python",
        "christian-kohler.path-intellisense"
    ]
}

深層学習モデルの実装・デバッグを簡単にする機能

深層学習モデルの実装を行う上で一番時間がかかるのは「モデルの入出力をする部分」と「モデル内のテンソル形状を合わせる部分」だと思います。もうここらへんもエーアイでなんとかしたいですが、そう簡単にはいきません。VSCodeデバッグ機能はこうした微妙の修正を必要とする部分で力を発揮します。

VSCodeの強力なデバッグ機能

深層学習モデルの実装で度々用いられるPyTorchによる実装をデバッグしている様子が以下のツイートで取り上げられています。

VSCodeではPython拡張機能をインストールしただけで次のようなことが可能です:

  • テンソルの値や形状が自動的に表示される(左画面)
  • マウスカーソルを変数に合わせるだけでテンソルの値や形状、重みやデバイスタイプまで確認できる

このように、深層学習モデルのデバッグに必要不可欠な情報が簡単に確認可能です。 一般的にデバッグをする際にはpdbといったデバッガを使用したり、printデバッグ を駆使していると思いますが、マウスホバーのみでテンソルの値や形状を確認することができ、こうした労力がほぼ0になります。

Pythonスクリプトデバッグ

VSCodeによるデバッグの流れとして、デバッグの設定を記述した launch.json を作成します。 launch.jsonの設定例として、以下のサイトに各プログラミング言語の例が掲載されています。 74th.github.io

今回は特にPythonを対象としているので、以下のページを見て設定します。

74th.github.io

具体的なデバッグの詳細については割愛します。公式サイトのページが特に詳しく紹介されているので参考にしてください。

code.visualstudio.com

AllenNLPモデルのデバッグ

深層学習による自然言語処理モデルを実装する際、AllenNLPを用いる方も多いのではないでしょうか? VSCodeデバッグ機能を用いてAllenNLPで実装したモデルをデバッグするには以下のサイトが参考になります。

docs.allennlp.org

デバッグ時に呼び出すスクリプトを記述します。 あとは launch.json に同様の手順でデバッグの設定を記述するだけのみです。

余談

ここからは私自身がおすすめするVSCodeの各種設定について述べます。

おすすめのショートカットキー・拡張機能・カスタマイズ

おすすめのショートカットキー

テキスト編集を効率よくできるショートカットキーとして私が多用しているものを列挙します。 以下はMacOSを想定したショートカットキー記述ですが、Windowsの場合は cmdalt に読み替えてください。

  • コマンドパレットを開く
    • 最重要ショートカットです。本記事でも何度も登場しました。
    • cmd + shift + p
  • サイドバーを開閉する
    • 左にあるサイドバーを表示したり隠したりします。エディタ領域が狭くなるので隠します。
    • cmd + b
  • ファイルエクスプローラを開く
    • ファイル一覧を見るのに使います。
    • cmd + shift + e
  • マルチカーソル系
    • 複数カーソルを表示して変数等を編集するときに使います
      • すべて変更する系
        • 選択中の語句をすべて選択する
          • cmd + shift + l
      • 特定の語句のみを対象として変更する系
        • cmd + d

おすすめの拡張機能

おすすめのカスタマイズ

このセクションでは、これまでに登場してきたおすすめ設定の全体を示します。 これらの設定の反映はコマンドパレットから > Preferences: Open Settings (JSON)settings.json を開いてコピペすることで反映されます。

{
    "editor.cursorStyle": "block",
    "editor.formatOnSave": true,
    "editor.minimap.enabled": false,
    "editor.formatOnType": true,
    "editor.codeActionsOnSave": {
        "source.organizeImports": true
    },
    "files.watcherExclude": {
        "**/.git/objects/**": true,
        "**/.git/subtree-cache/**": true,
        "**/node_modules/**": true,
        "**/dataset/**/*.{png,zip,jpg,npz}": true,
    },
    "remote.containers.defaultExtensions": [
        "christian-kohler.path-intellisense",
        "davidhouchin.whitespace-plus",
        "JoeBerria.statusbarerror",
        "ms-python.python",
        "streetsidesoftware.code-spell-checker"
    ],
    "python.formatting.provider": "black",
    "python.linting.flake8Enabled": true,
    "python.linting.pylintEnabled": false,
    "python.jediEnabled": false,
    "python.linting.flake8Args": [
        "--ignore=E501,W503"
    ],
    "python.sortImports.args": [
        "-m 3"
    ],
    "statusbarerror.wholeLine.show": true,
    "window.zoomLevel": 0,
    "window.title": "${folderPath}${separator}${activeEditorShort}${separator}${rootName}",
    "workbench.colorTheme": "Solarized Dark+",
    "workbench.startupEditor": "newUntitledFile",
    "workbench.colorCustomizations": {
        "editorCursor.foreground": "#FFFF00"
    },
    "cSpell.userWords": [
        "conv",
        "cuda",
        "cudnn",
        "lstm",
        "ndarray",
        "numpy",
        "relu",
        "sklearn",
        "tqdm",
    ],
}

以下はこれまで紹介してこなかった設定についてコメントをいれます:

  • "editor.formatOnSave": true
    • ファイルを保存するときにフォーマッタを実行します。特にPythonのフォーマッタであるblackにより、常にコード規約に従った整ったコードを維持できます。
  • "editor.codeActionsOnSave"
    • "source.organizeImports": true
      • ファイルを保存するときにimport文を整理します。特にPythonのisortによって、import文が常に整理された形で維持できます。
  • "editor.minimap.enabled": false
    • ミニマップの表示をoffにします。これいります?
  • "files.watcherExclude"
    • 変更監視を除外するパターンを定義します。深層学習ではたくさんのファイルを扱うため、特に .jpg.png といった画像ファイルや .csv.csv といったテキストファイルを予め除外しておくことをおすすめします。
    • ディレクトリ構造に合わせて適宜変更することをおすすめします。
  • "cSpell.userWords"
    • スペルチェック時に除外する単語群を定義します。

Emacsから乗り換え

私はこれまでEmacsディストリビューションの1つであるSpacemacsを使っていました. 本記事を執筆するにあたり、これまで使ってきたEmacsの操作感にできるだけ近くなるようにいくつか設定しました。以下に詳細を紹介します。

代替となるVSCodeの機能や拡張機能

M-x から始まるコマンド実行

  • コマンドパレット
    • Emacsでは M-x から始まるコマンドが数え切れないほどあります。VSCodeのコマンドパレットはEmacsM-xと同様の立ち位置でして、本記事でもコマンド実行の際に様々な場面で登場してきました。

Emacsキーバインド

カラースキーマ

代替となるショートカットキー

これまで愛用してきたEmacsの操作感に近づけるためにキーバインドの追加や変更は必須です。 キーバインドの変更はコマンドパレットから > Preferences: Open Keyboard Shortcuts (JSON) を選択することで、keybindings.json が開きますので、こちらを追加していきます。 私は現在、以下のキーバインドを定義して使用しています:

[
    {
        "key": "ctrl+i",
        "command": "editor.action.indentLines",
        "when": "editorTextFocus && !editorReadonly"
    },
    {
        "key": "cmd+.",
        "command": "editor.action.revealDefinition",
        "when": "editorHasDefinitionProvider && editorTextFocus && !isInEmbeddedEditor"
    },
    {
        "key": "cmd+,",
        "command": "workbench.action.navigateBack"
    },
    {
        "key": "ctrl+x p",
        "command": "workbench.action.navigateBack"
    },
    {
        "key": "ctrl+x m",
        "command": "workbench.view.scm"
    },
    {
        "key": "ctrl+c ;",
        "command": "editor.action.commentLine",
        "when": "editorTextFocus && !editorReadonly"
    },
    {
        "key": "cmd+w",
        "command": "-workbench.action.closeWindow",
    },
    {
        "key": "cmd+w",
        "command": "-workbench.action.closeActiveEditor"
    },
    {
        "key": "cmd+w",
        "command": "-workbench.action.closeGroup",
    },
    {
        "key": "cmd+w",
        "command": "emacs-mcx.copyRegion",
        "when": "editorTextFocus"
    }
]

Emacsでは分割した画面を移動する際に C-x o (Ctrl + x o) を頻繁に利用しますが、この逆の操作 C-x p のようなもの*3VSCodeおよび追加したEmacsキーバインドの拡張にはありませんでした。 そこで次のような設定を定義することで操作を追加します:

{
    {
        "key": "ctrl+x p",
        "command": "workbench.action.navigateBack"
    }
}

代替できなかったEmacsの機能や拡張機能

VSCodeを使ってきて、EmacsにあってVSCodeに無くクリティカルに重要であった機能は今の所私のユースケースではなさそうです。しかしながらEmacs Lispには便利な拡張がたくさんあり、以下にいくつか紹介したいと思います。代替できそうな拡張機能をご存知ある方はぜひ @shunk031 までお知らせください。

dotfilesとして設定を管理する

これまでたくさんの拡張機能の導入や、それに伴った settings.jsonkeybindings.json の設定を行ってきました。 これらをGitHub等で管理することで、違うデバイスでも同じ環境でコードを書くことが可能です。

私はもともとGitHub上でdotfiles*4を管理しているため、VSCodeの設定ファイルもdotfilesに含めて管理しようと考えました。

github.com

具体的には、dotfilesディレクトリ内の settings.json および keybinding.json からもともとあった設定ファイルの場所にシンボリックリンクを張ります:

$ ln -sf ~/.dotfiles/.vscode.d/settings.json ~/Library/Application\ Support/Code/User/
$ ln -sf ~/.dotfiles/.vscode.d/keybindings.json ~/Library/Application\ Support/Code/User/

こうすることでGitHubで設定ファイルを管理する体制ができるわけですが、最新版ではVSCodeが設定ファイルの同期をサポートし始めました。

forest.watch.impress.co.jp

お好きな方法で設定ファイルを管理することをおすすめします。

おわりに

本記事では、深層学習モデルの実装に頻繁に利用されるPythonを対象に、深層学習モデルの実装を爆速にする設定や機能について紹介しました。 リモートにあるGPUサーバに簡単に接続が可能であり、またリモート上のコードの編集やデバッグが容易であることを確認しました。これらの機能をフル活用することにより、今まで以上に深層学習モデルの実装が高速に行える可能性があると考えています。

また、Emacsから乗り換えを検討している方たちに向けて、代替可能な拡張機能やショートカットキーを示し、代替ができていない拡張機能についても示しました。これらの拡張機能は自身で作ることが可能なので、少しずつ穴を埋められるような拡張機能を作れたらよいなと考えています。

参考記事

Windows向け

phst.hateblo.jp

*1:PEP 501 -- General purpose string interpolation | Python.org https://www.python.org/dev/peps/pep-0501/

*2:PEP 503 -- Simple Repository API | Python.org https://www.python.org/dev/peps/pep-0503/

*3:EmacsでC-x oの逆動作をC-x pに割り当てる - 拡張現実ライフ

*4:. (ドット) から始まる設定ファイルのことです。.bashrc や .zshrc 、tmux.conf 、.vimrc などを指します。