まるまろぐ

本ブログに記載の情報は全て飼い犬が書いたものであり、その内容に誤りや欠陥があった場合にも、私は一切の責任を負いません。

TSUBAME3.0の使い方

はじめに

この記事はもともと岡崎研究室の新メンバーに向けて内部Wikiに書いたものを少し編集し公開したものです。なのでグループやグループディスクが既に存在している前提で書かれていますが、所属可能なTSUBAMEグループがない場合は新しくグループを作る必要があります。また、この記事は初心者向けかつ研究室のメンバー向けに情報を絞って書かれています。より多くの機能を知るにはこの記事の最後に挙げられているような一次情報に当たってください。

アカウントの取得

まだTSUBAMEアカウントを持ってない場合は取得する必要があります。東工大の学生または職員であれば東工大ポータルにログインし、「TSUBAME ポータル」リンクから申請してください。 - 学生や職員でない場合はここを参考に取得してください。

なお、課金するにはグループに追加されている必要があります。アカウントの取得後、研究室などのグループに追加してもらってください。

.ssh/configの設定

自分が利用するMacbook等のクライアントの~/.ssh/configに以下の設定をしておきましょう(下二行は設定しないと接続が切れる)。

Host tsubame
    User {your TokyoTech ID or TSUBAME ID}
    HostName login.t3.gsic.titech.ac.jp
    ServerAliveInterval 120
    ServerAliveCountMax 30

ログイン

  1. TSUBAME ポータルにログインし、sshするために公開鍵を登録する
  2. ssh tsubameでログイン

これでログインノードにログインできました。

TSUBAMEの環境

ここでは、TSUBAMEのストレージとソフトウェアについて述べます。

ストレージ

ホームディレクトリの容量は25GBしかないので、グループディスクと呼ばれるストレージをグループごとに購入して使うことになります。グループのストレージへのパスを誰かに聞く必要があるでしょう。 基本的には全てこのディレクトリ下に保存したほうがいいと思います。

ソフトウェア

TSUBAMEでは、moduleコマンドを使用することでコンパイラやアプリケーションの切り替えを行うことができます。 使えるmoduleを確認してみましょう。

module avail

python3をロードしてみましょう。

python --version
module load python/3.6.5
python --version

他には、module listで現在利用しているmoduleを確認したり、module unload {module name}でunloadしたり、module purgeで初期化することなどができます。

ジョブ実行

ログインノードでは重い計算はできないので、計算ノードで行う必要があります。

計算ノードでジョブを実行する方法には - インタラクティブ実行(qrsh) - バッチ実行(qsub) - 通常実行 - 予約実行

があります。また、計算ノードには資源タイプという概念があり目的に合わせて選ぶことになりますが、ざっくり言うと - GPUを1つ使いたい:q_node - GPUを4つ使いたい:f_node - CPUだけ使う:q_core - メモリをたくさん使う:f_node

あたりを選ぶといいです。詳しくは講習会TSUBAME利用法スライドが参考になります。

インタラクティブ実行

普段のCLIのように対話的にプログラムを実行するには、qrshコマンドを使います。

qrsh -g {your-group-name} -l q_core=1 -l h_rt=00:30:00 -p -4  

上記で使われているオプションを以下に示します。

オプション 説明
-g TSUBAME3グループ名を指定します。指定しないとお試し実行になります。
-l [資源タイプ名]=[個数] 資源タイプおよびその個数を指定します。
-l h_rt=[時間] 時間を指定します。
-p [-5 | -4 | -3] ジョブの実行優先度を指定します。 -3,-4を指定すると通常よりも高い課金係数が適用されます。-4は-5の2倍、-3は-5の4倍お金がかかります。

終了するときは普通にexitしてください。

バッチ実行

バッチ実行では、ジョブスクリプトを記述してそれをqsubコマンドによって投入します。

ジョブスクリプトの作成

以下にジョブスクリプトの例を示します。なお、qsubコマンドのオプションはqrshと同じですが、コマンドラインで指定することも、以下のようにスクリプトファイルの最初のコメントに書いておくこともできます。ただし-gオプションだけはコマンドの引数として指定する必要があります。

#!/bin/sh

# カレントディレクトリでジョブを実行する場合に指定
#$ -cwd
# ノードのタイプと数を指定
#$ -l f_node=1
# 実行時間を指定
#$ -l h_rt=0:10:00
# ジョブ名(指定しない場合はスクリプトファイル名になる)
#$ -N test
# 標準出力ファイル名(指定しないとジョブの名前とIDを元に生成される)
#$ -o test_job.out
# 標準エラー出力ファイル名(同上)
#$ -e test_job.err
# メールを送信する条件を指定(a:中止時、b:開始時、e:終了時)
#$ -m abe
# 送信先メールアドレス
#$ -M example@example.com


# Moduleコマンドの初期化(必ず行うこと)
. /etc/profile.d/modules.sh
# CUDA&cuDNN環境の読込
module load cuda/9.0.176
module load cudnn/7.3

# プログラムの実行
python -c 'import this'

オプションについて詳しくはこちら

スクリプトの実行

上記のようなスクリプトをjob.shというファイル名で保存したとすると、ジョブは次のように実行できます。

qsub -g {your-group-name} -p -4 job.sh

ジョブの確認や削除

  • 確認:qstat
  • 削除:qdel {job-ID}

予約実行について

上記のような通常実行では1つのジョブに最大24時間までしか指定することができません。それ以上使いたい場合には、予約実行をする必要があります。予約はTSUBAMEポータルから行い、与えられた予約IDを-arオプションで指定してqsubすることで実行できますが、ここでは詳しく触れません。利用の手引きを参考にしてください。

この記事で説明されていないこと

  • アレイ実行
  • 依存実行
  • 並列化(複数ノードの使用)

Tips

スペック

TSUBAME

  • ノード数:540
  • GPU:Tesla P100 (NVlink)

詳しくは

各ノード

資源タイプ名 CPUコア数 メモリ (GB) GPU
f_node 28 240 4
q_node 7 60 1
q_core 4 30 0

詳しくは https://helpdesk.t3.gsic.titech.ac.jp/manuals/handbook.ja/jobs/

利用料金

ポイント制。東工大の学内の人間が使う場合利用料金が75%オフになる。 - 購入代金:720,000ポイント / 5,000円 (学内の場合)

消費ポイントの計算式は以下の通り。

消費ポイント=
利用ノード数×資源タイプ係数×優先度係数×(0.7× 実際の実行時間(秒) + 0.1×指定した実行時間(秒))
  • 例:f_nodeを1つ24時間指定した上で24時間優先度-4で使った場合、138,240ポイント消費する(金額に換算すると960円)

その他

  • ログインノードはlogin0とlogin1のふたつあり、sshすると自動的にどちらかに振り分けられる(通常は気にする必要はない)

ドキュメント

JupyterLabでtqdmを使えるようにするためにcondaでnodejsとipywidgetsをインストールする

初期状態のJupyter Labでtqdmtqdm_notebookを使おうとしてもうまく動作しません。 これを解決するためには、ipywidgetsのJupyterLab Extensionをインストールする必要があります。

ipywidgetsのインストール

まだipywidgetsがインストールされていない場合は以下のどちらかの方法でインストールしてください。

pip install ipywidgets
jupyter nbextension enable --py --sys-prefix widgetsnbextension

もしくは

conda install -c conda-forge ipywidgets

JupyterLab Extensionのインストール

JupyterLab Extensionをインストールするにはnodejsもインストールされている必要があるので、まず以下のコマンドを実行します。

conda install -c conda-forge nodejs

それからlabextensionをインストールします。

jupyter labextension install @jupyter-widgets/jupyterlab-manager

結果

バーが無限に生成されなくなってうれしい

余談

JupyterLabでtqdmを使えるようにしたいという話自体は既にいろんな人がしているのですが、nodejsを入れる手段がいろいろあるもののどれも冗長だったのでなんかないかな~と思っていたところipywidgetsの公式ドキュメントにcondaでnodejsを入れられると書いてあり、jupyterを使う人達にとってはPPAとかn packageとかnodebrewとかが出てきて新しいよとかバージョン管理できるよと言われるよりcondaでポンと入ってしまったほうがうれしいのではないかと思い書きました。

参考文献

Installation — Jupyter Widgets 7.5.0 documentation

aptでインストール済みのパッケージ構成を(他のサーバで)復元する

古いサーバにaptでインストールされているパッケージたちを新しいサーバにもインストールする必要があり、とりあえずググって出てきた方法で試したがうまくいかず、他にないか探していたらちょうどいいものがあったのでメモ。

環境

移行前、移行先のサーバ共にUbuntu Server 18.04 LTS

手順

1. 移行前のサーバ

sudo apt update & upgrade
sudo apt install apt-clone
sudo apt-clone clone ~/hoge

すると、インストールできないパッケージ等の情報が標準出力に出るとともに、hoge.apt-clone.tar.gzが生成されるので、scpなどで移行先のサーバに送ってください(自分はディレクトリがマウントされていたので送る必要はなかったけど)。

2. 移行先のサーバ

sudo apt update & upgrade
sudo apt install apt-clone
sudo apt-clone restore ~/hoge.apt-clone.tar.gz

以上でインストールは完了です。

余談

もともとはこちらなどに書かれているように、dselectを使ってインストールしようとしていました。しかし、 f:id:hidamarumaru:20181109202928p:plain という警告が出て、まあ入れ直すのだから大丈夫だろうとは思いつつも、highly recommendedと言われてるし、ググってもこの警告に関して言及してる人が見当たらなかったこと、そもそも手順がややこしくpippip freeze > requirements.txtpip -r requirements.txtみたいにあっさり移行できる方法がないのかと思ったこともあり、改めて他の手段を探すことにした結果、apt-cloneを見つけて使うことにしました。そのとき日本語の情報が見当たらなかったのでこの記事を書くことにしました。

上のダイアログでNoを選んでも無事インストールできていたのか気になる……。

参考

https://github.com/mvo5/apt-clone

Hugo + Academic + Netlify で一瞬でウェブサイトを作って公開する

記事タイトルで一瞬でウェブサイトを作るとか言ってるので、何が起きているのかの説明は後回しにして、まずは最短の手順を示したいと思います。

1. GitHub 上に Academic のテンプレートをダウンロードしつつ Netlify と連携

以下のリンクを踏んで緑色のボタンをポチポチしてください。GitHub アカウントを持っていない場合は作ってください。

https://app.netlify.com/start/deploy?repository=https://github.com/sourcethemes/academic-kickstart

するとこんな感じの画面になると思います。 f:id:hidamarumaru:20180820200141p:plain これでもうウェブサイトは完成し公開されました。上の画像で言うと https://objective-sammet-5a4f1a.netlify.com がウェブサイトのURLで既にアクセスできるわけですが、もしこの自動的に割り当てられたURLが嫌な場合は Site settings から Change site name ボタンを押すことで変えられます。独自ドメインも使えますがここでは触れません。

2. GitHub から更新する

次はウェブサイトの内容を編集します。先ほどの手順によって GitHubリポジトリが作成されているはずです。リポジトリ名を変更していなければURLは https://github.com/username/academic-kickstart になっているはずです(username は適宜置き換えてください)。 まずはconfig.tomlを編集してみましょう。git cloneしてもいいのですが、ここでは簡単のため GitHub 上で直接いじります。config.tomlのページに移動したあと、ペンっぽいアイコンをクリックしてください (下の画像で矢印が指してる先です)。

f:id:hidamarumaru:20180820204419p:plain

すると編集できるようになるので、
title = "Academic"
となっているところを
title = "Test"
と書き換えてください (もちろん Test じゃなくても自分の名前でもなんでも良いです)。 それから、59行目の
color_theme = "default"

  • ocean
  • forest
  • coffee
  • dark
  • 1950s

のいずれかに変えてください。

できたらページの一番下までスクロールして Commit changes をクリックしましょう。しばらく待つと自動的にウェブサイトの内容が更新されているはずです。同様の方法でconfig.tomlcontentディレクトリ内の様々なファイルを編集し commit すればウェブサイトの各コンテンツを更新できます。ファイルを見ればどこをどう編集すればよいかというのはだいたいわかると思います。たとえば、Biography を編集したい場合はcontent/home/about.mdを開いて一番下の

# Biography

Lena Smith is a professor of artificial intelligence at the Stanford AI Lab. Her research interests include distributed robotics, mobile computing and programmable matter. She leads the Robotic Neurobiology group, which develops self-reconfiguring robots, systems of self-organizing robots, and mobile sensor networks.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed neque elit, tristique placerat feugiat ac, facilisis vitae arcu. Proin eget egestas augue. Praesent ut sem nec arcu pellentesque aliquet. Duis dapibus diam vel metus tempus vulputate. 

となっている部分を

# 自己紹介

こんにちは

と書き換えてください。もちろん、これはただの Markdown 記法なので、見出しを追加したり、シンタックスハイライトをつけたりすることもできます。 f:id:hidamarumaru:20180820222147p:plain より高度な編集をしたい場合は 公式ドキュメント を参照してください。

何が起きているのか?

Hugo

上記の手順では全く表に出てきませんでしたが、このウェブサイトを作る上で裏では Hugo という静的ウェブサイトのジェネレータが動いています。Academic は Hugo のテーマのひとつです。リポジトリthemesを開いてみると入っているのがわかると思います。テーマの一覧は

Complete List | Hugo Themes

で見ることができ、Netlify との連携を提供してくれているテーマであれば Academic 以外のテーマでも今回のようなことができます。

Netlify

Netlify は静的サイト用のホスティングサービスです。本来であれば更新をサイトに反映するには Hugo がページを生成するためにhugoコマンドを打ち、それから生成したファイル群をサーバにデプロイしなければいけないのですが、Netlify が そのへんのことを GitHub に変更が加えられるたびに勝手にやってくれています。そして、その勝手にやってもらうための設定もテーマの製作者が用意して提供してくれているので、もはや我々は何もする必要がなかったわけですね。ただ、Netifly は本当に簡単なのでやろうと思えばすぐに自分でも自動化できます。ちなみに設定はリポジトリnetlify.tomlや Netlify 上の Settings の Build & deploy にあります。

Ubuntu のユーザにあとからホームディレクトリを設定する方法

日本語で「Ubuntu ホームディレクトリ あとから」とググってもなぜか誰も言及してる人がいなくて、ないのか……と思ったが英語で検索してみたらあったのでメモ。

mkhomedir_helper <username>

と打てばそのユーザーのホームディレクトリがuseradd-mオプションを指定した時のようにいい感じで作成されます。

参考:Ubuntu Manpage: mkhomedir_helper - Helper binary that creates home directories

[Python]ファイルオブジェクトを特定の文字列で分割しながら読み込む

実行環境


たとえば、次のような txt ファイルがあったとします。

寒い冬が北方から、狐の親子の棲んでいる森へもやって来ました。
EOS
 或朝洞穴から子供の狐が出ようとしましたが、
「あっ」と叫んで眼を抑えながら母さん狐のところへころげて来ました。
EOS
「母ちゃん、眼に何か刺さった、ぬいて頂戴早く早く」と言いました。
EOS

このテキストをEOSごとに分割して何かをすることを考えます。 一番簡単な方法は、一度read()で読み込んでしまい、split()を使って分割することです。

with open('example.txt') as f:
    txt = f.read()
    txt_list = txt.split('EOS')
    for lines in txt_list:
        # 何か操作をする

これはうまくいきます。しかしファイルオブジェクトを一度に読み込んでしまっているので、ファイルサイズが小さい時は良いですが、大きすぎる時には避けたい手段です。
そこで、素直にEOSが来るまで各行をappend()してリストに保持しておき、EOSが来たらそのリストを処理することを考えます。

with open('example.txt') as f:
    lines = []
    for line in f:
        if line == 'EOS\n':
            for li in lines:
                # 何か操作をする
            lines = []
        else:
            lines.append(line)

これは先ほどより良いやり方ですが、EOSの間隔が極端に大きかった場合、結局一度にたくさん読み込んでしまうことになります。それに、できれば一度forで回したものを保持してまたforで回すというのは同じことの繰り返しなのでやりたくありません。
そこで、iter()を使うことを考えてみます。iter()公式ドキュメントにも記載されているように、第二引数に文字列を与えることで、その文字列が出てくると止まるイテレータを作ることができ、特定の文字列までファイルオブジェクトを読み込みたいときに便利です。

with open('example.txt') as f:
    while True:
        for line in iter(f.readline, 'EOS\n'):
            if line == '':
                break
            # 何か操作をする
        else:
            continue
        break

readlineは終端まで行くと空文字列を返すので、それを利用してループを抜けています。多重ループを抜けるためにfor-elsecontinueを使っています。これらについては公式ドキュメントのチュートリアルが、またPythonの多重ループの抜け方についてはこちらの記事が参考になるかと思います。
この方法は先ほどの問題を解決していますが、コードが複雑になります。そこで明示的にファイルの終端を求めることを考えてみます。

with open('example.txt') as f:
    f.seek(0,2)
    size = f.tell()
    f.seek(0)
    while f.tell() < size:
        for line in iter(f.readline, 'EOS\n'):
            # 何か操作をする

この方法は多重ループを抜けるために複雑な制御構文を書く必要がなく、for文を内包表記にすることも可能ですが、Pythonではファイルオブジェクトのサイズを一発で知ることはできないため、何行か余計に書く必要があります。 また、ファイルオブジェクト以外にこの手法を取ることはできません。

色々と検討してきましたが、どれも一長一短でたったひとつの冴えたやり方を見つけだすには至りませんでした。
最初の方法以外は一行ごとの読み込みであり純粋な分割ではないのも気になるところではあります(ほとんどの場合はメリットとして働くでしょうけど)。

指摘、追加、修正、質問などあればコメントまでよろしくお願いします。

技術系のブログをはじめようと思います

最近はパソコンを使ってなんやかんやすることも多くなってきたので、備忘録として新しくブログを始めることにしました。

検索エンジンから来た人が記事を読むことを全く想定しないわけではないですが、きっちり書くのであれば自前のブログを用意するよりQiitaとかに投げたほうがいいのかな、という気もするので、あくまで日記的なノリで書いていこうかなと思っています。