Thinkpad T480sのUbuntu 18.04にBumblebeeを設定したメモ

このエントリーをはてなブックマークに追加

Thinkpad T480s(CPU: i5-8250U / dGPU: GeForce MX150)にUbuntu 18.04.1(Kernel: 4.15.0-44-generic)をインストールしたのだがGPU周りでハマった。

何にハマったのかと言うと、dGPU(GeForce MX150)と内臓GPU(UHD620)の切り替え、協調処理の設定だ。Linuxを利用する場合にIntel以外のGPUは基本的に鬼門だし、ましてやノートPCで外部GPUはハマりまくる。でも(できもしないのに)時代はディープラーニングだし当然(使いもしないのに)CUDAとか欲しかったし、ノートPCなのにハイパフォーマンスとか、普段は内蔵GPUなのに負荷が高いときにdGPUへ処理をオフロードしてブーストするOptimus機能とか厨二病を痛く刺激されたのだ。だって格好良いじゃん。

もちろん余計なことをせずdGPUのみを利用するという方法もある。その場合でも動作自体には大きな問題はないが、なにせノート用とはいえ独立GPUのため消費電力が大きい。つまりバッテリー駆動時間に大きな影響がある。具体的にはT480sに搭載されている低電力版MX150(1D12)はTDP 10Wあり、これがそのままi5-8250UのTDP 15Wに乗ってくると思われ単純計算で1.7倍前後の消費電力となる。つまり駆動時間が約半減するわけだ。これは痛い。

Linuxにおいて消費電力を抑えつつNVIDIAのdGPUを利用する方法は2つある。1つ目はPRIME、2つ目はBumblebeeだ。PRIMEは静的な切り替え、BumblebeeはNVIDIA特有のOptimusをLinuxから利用する技術である。簡単に言うとPRIMEは描画セッション自体を切り替える必要があるが、Bumblebeeは同一のセッション内でもProxyを通してプロセス毎にdGPUと内臓GPUを変更することができる・・・らしい。

プロプライエタリドライバのインストール

下記で390.77のプロプライエタリドライバをインストールし、OSS版のドライバをアンインストールする。

sudo apt-get install nvidia-390
sudo apt-get remove xserver-xorg-video-nouveau

基本的にはこれでPRIME機能は利用できるようになる。
切り替え処理は下記のコマンドで行う。ただし切り替え処理を行っても、実際のGPUの切り替え処理はGDMセッションの再起動、つまりログアウト、ログインが必要になる。

# 現在利用しているGPU
sudo prime-select query

# 内蔵GPUに切り替え
sudo prime-select intel

# 独立GPUに切り替え
sudo prime-select nvidia

なお、必ず下記の設定とインストールを始める前に prime-select intel をして再起動しておくこと。

Bumblebeeの設定とインストール

最新の390.77のドライバとUbuntu18.04の場合の組み合わせの場合Qiita等に存在する手法だと動かない、具体的にはドライバの場所が異なるためBumblebeeが正常に動かないのだ。同様の質問は海外でも出ており、下記のアドレスに記述されている手法で基本的には上手く機能する。

Dont working on my Linux mint 19 · Issue #971 · Bumblebee-Project/Bumblebee

下記は自分が実施した手順となる。

1. Bumblebee関連のパッケージのインストール

primusはoptimusrunの代わりになる何からしく速いとかなんとか・・・、別に入れなくても動くはず。また上記リンクのようにPPAのリポジトリは追加せず標準のリポジトリでなんとかなる。

# Bumblebeeのインストール
sudo apt-get install bumblebee primus primus-libs-ia32 linux-headers-$(uname -r) bumblebee-nvidia

2. 各種設定ファイルを修正

/etc/bumblebee/bumblebee.conf でライブラリパスの修正を行う、ここがQiitaなどで多く見られるドキュメントとは異なる。具体的にはLibraryPathが全く違うため下記のように書き換える。

# ファイルを開く
sudo vi /etc/bumblebee/bumblebee.conf

# 書き換え対象箇所
LibraryPath=/usr/lib/nvidia-current:/usr/lib32/nvidia-current
XorgModulePath=/usr/lib/nvidia-current/xorg,/usr/lib/xorg/modules

# 変更後の内容
LibraryPath=/usr/lib/x86_64-linux-gnu:/usr/lib/i386-linux-gnu
XorgModulePath=/usr/lib/x86_64-linux-gnu/nvidia/xorg,/usr/lib/xorg/modules,/usr/lib/xorg/modules/input

/etc/environment に下記変数を追加する。この変数に関しては正直意味がわからないがやれと書いてあるのでやる。

# ファイルを開く
sudo vi /etc/environment

# 下記一行を追加する
__GLVND_DISALLOW_PATCHING=1

Bumblebeeは仮想的なドライバを噛ませるというような仕組みらしく、起動時に内蔵GPUや仮想ドライバに先んじてロードされないようにmodprobeのブラックリスト /etc/modprobe.d/blacklist-nvidia.conf に追加しておく。

# ファイルを開く
sudo vi /etc/modprobe.d/blacklist-nvidia.conf

# 下記の内容を追加する
blacklist nouveau
blacklist nvidia
blacklist nvidia-drm
blacklist nvidia-modeset
alias nouveau off
alias nvidia-drm off
alias nvidia-modeset off

primusはドライバのパスが異なるようなので下記のようにシンボリックリンクを作成しておく、primus実行時にエラーが出たら修正でも構わない。

sudo ln -s /usr/lib/x86_64-linux-gnu/libGL.so.1 /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1

3. gpumanagerを無効化する

grubの起動オプションとして設定ファイル /etc/default/grub にnogpumanagerを追加し、update-grubする。これはgpu-managerがxorg.conf等を改変したりするのを防ぐためらしい。

# ファイルを開く
sudo vi /etc/default/grub

# 下記の内容を末尾に追加する
GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX nogpumanager"

# update-grub処理
sudo update-grub

4. 必要のないサービスの停止

nvidia関連の必要のないサービスを下記コマンドで停止する

sudo systemctl disable nvidia-fallback.service
sudo systemctl disable nvidia-persistenced.service

5. 再起動と動作確認

再起動をする。

再起動後にnvidiaのドライバ状態を確認、intelの内蔵GPUを利用しているのでロードされておらず状態取得に失敗する。

# nvidiaドライバの状態をチェック
$ nvidia-smi
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.

optirunをブリッジにprimusを設定してglxgearsを実行する。

optirun -b primus glxgears

別ウインドウが開き、ギアがくるくる回ってたらとりあえず成功なので、その状態で再びnvidia-smiを実行すると下記のようにnvidiaのドライバがロードされ実行されていることがわかる。

optirunを通じて実行されているプロセスがなくなるとnvidiaドライバは自動的にアンロードされ再びnvidia-smiを実行するとエラーが出るようになる。

6. ベンチマークとかでdGPUを実感する

Uniqine Heavenなどのベンチマークをダウンロードし実行してみる。すると内蔵GPUで実行する場合とoptirunを利用してMX150経由で実行する場合とで大きな差が出ることがわかり、とても嬉しい。

参考URL