MySQLでダンプをインポートする際に「cannot creat a JSON value from a string with CHARACTER SET 'binary'」と表示されてインポートができない

TL;DR

文字コードをバイナリモードで出力しちゃった説

ヘッダー部分?を binary から utf8mb4 などに変更してインポートしなおす

- /*!40101 SET NAMES binary */;
+ /*!40101 SET NAMES utf8mb4 */;

データに16進表記のバイナリデータが含まれる説

JSON型のダンプなどでテキストデータでなく、16進表記のバイナリが入っちゃうことがあるらしい

-- 中身は適当
INSERT INTO hoge (`id`, `json_column`)
VALUES
    (1, X'573DA6CD8B49C5DD1E02AEA76876754F'),
    (2, X'134715474B24EC215B49BACE9B82561D');

CONVERT関数で文字列に直せばよい

INSERT INTO hoge (`id`, `json_column`)
VALUES
    (1, CONVERT(X'573DA6CD8B49C5DD1E02AEA76876754F' using utf8mb4)),
    (2, CONVERT(X'134715474B24EC215B49BACE9B82561D' using utf8mb4));

Stable Diffusion を NVIDIA Container Toolkit で動かす

目次

経緯

最近よく Twitter で Midjourney や Stable Diffusion といった画像生成AIを見かけるようになり、ふーんと思っていたのですが、 Stable Diffusion がオープンソース化されたということで、せっかくGPUも積んでいることだしローカルで構築してみようと思いました。
また、調べてみるとホストマシンに Python をインストールしたり、Google Colab を使って構築している人はいました。しかし、宗教上の理由であまりホストマシンに Python 開発環境をそのまま入れたくなかったため、前職でも使ったことのある NVIDIA Container Toolkit を使ってみようと思いました。

環境

項目
OS Windows 10 Pro(WSL2)
CPU Intel Core i9-9900K
RAM DDR4-3600 64GB
GPU Geforce RTX 3080 Ti 12GB
Docker 20.10.11
NVIDIA Driver 512.15
CUDA 11.6
ベースイメージ nvcr.io/nvidia/pytorch:22.07-py3(※)

※このイメージは CUDA11.7 なので、互換モード(?)で動くみたいです。 本当は自分の環境だと PyTorch:22.02 を使用したほうがよさそうです。

環境構築

NVIDIA Container Toolkit のインストール

// TODO: 別な記事にまとめるかも……

PyTorch コンテナの立ち上げ

下記コマンドでコンテナに GPU を割り当てて起動します。

$ docker run --gpus all -it --rm nvcr.io/nvidia/pytorch:22.07-py3

必要パッケージのインストール

下記コマンドでインストールします。

pip install diffusers==0.2.4 transformers scipy ftfy

Hugging Face の登録・アクセストークン生成

学習済みモデルが公開されている Hugging Face のアカウントを作成し、アクセストークンを生成します。
Hugging Face にアクセスし、右上の Sign Up からアカウントを作成し、メールアドレス認証を済ませます。
次にアクセストークンを生成します。右上のアカウントアイコンをクリックし、 Settings を開きます。
左メニューの Access Tokens を開き、 New Token をクリックし、トークンを生成します。トークンの種類は Read で大丈夫です。

Stable Diffusion の学習済みモデルへアクセス

Stable Diffusion のページへアクセスし、ライセンスをよく読んで Access Repository をクリックします。

コーディング

ここからは公式の記事をなぞっていく感じになります。

from diffusers import StableDiffusionPipeline

YOUR_TOKEN={先ほど生成したアクセストークン}
# 学習済みモデルのロード
pipe = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v1-4", use_auth_token=YOUR_TOKEN)
pipe.to("cuda")

# 生成に使用する文
prompt = "a photograph of an astronaut riding a horse"
# 生成
image = pipe(prompt)["sample"][0]

# 保存
image.save(f"hoge.png")

学習済みモデルをロードする際に、VRAM が 10GB 未満の場合は、下記のように半精度浮動小数を指定したほうが良いらしいです。

pipe = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v1-4", revision="fp16", torch_dtype=torch.float16, use_auth_token=YOUR_TOKEN)

a photograph of an astronaut riding a horse

躓いたところ

恐らくどっちも自分の環境の問題だと思います。

Docker が WSL2 を巻き込んで落ちた

  • モデルのロード時や docker commit を実行した際に、Docker と WSL2 が落ちました。
  • 原因は恐らくディスクとメモリがいっぱいだったからっぽいです……たぶん……。
    • 複数ブラウザ併用してタブを数百個とか開いてる人が悪い。

ホストのグラフィックドライバが落ちた

  • 画像生成した後放置して他の作業をしていたら突然グラフィックドライバが落ちました。
  • 原因は VRAM が足りていなかったみたいです。
    • これも恐らくブラウザとかでVRAMが使用されていたみたいです。

参考

認証プロキシ+独自リゾルバの環境でDockerデーモンが正常に動かない(未解決)

目次

事象

Dockerデーモンが外部アクセスするような操作(pull とか)を実行する際、下記のようなエラーが発生する。

Error response from daemon: Get "https://registry-1.docker.io/v2/": dial tcp 3.229.227.53:443: i/o timeout
Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
Error response from daemon: Get "https://registry-1.docker.io/v2/": context deadline exceeded

環境

項目
OS Ubuntu 20.04 Linux 5.11.0-27
Docker 20.10.11

設定値

項目
DNSサーバ 192.0.2.254
プロキシ http://192.0.2.253:8080
プロキシユーザ user
プロキシユーザパスワード Passw0rd

やったこと

プロキシサーバ環境変数の設定

~/.zshrc

export http_proxy=http://user:Passw0rd@192.0.2.253:8080
export https_proxy=http://user:Passw0rd@192.0.2.253:8080
export HTTP_PROXY=http://user:Passw0rd@192.0.2.253:8080
export HTTPS_PROXY=http://user:Passw0rd@192.0.2.253:8080

Dockerデーモンが使用するDNSサーバの設定

/etc/docker/daemon.json

{
    "dns": [
        "192.0.2.254"
    ]
}

Dockerデーモンに渡すプロキシサーバ変数の設定

/etc/systemd/system/docker.service.d/override.conf

[Service]
Environment='HTTP_PROXY=http://user:Passw0rd@192.0.2.253:8080' 'HTTPS_PROXY=http://user:Passw0rd@192.0.2.253:8080'

ユーザごとのDockerで使用するプロキシサーバ変数の設定

~/.docker/config.json

{
    "proxies": {
        "default": {
            "httpProxy": "http://user:Passw0rd@192.0.2.253:8080",
            "httpsProxy": "http://user:Passw0rd@192.0.2.253:8080"
        }
    }
}

まとめ

  • 認証プロキシつらい
  • パブリックDNSを使わせてほしい
  • 誰もこの環境で困っていないのだろうか……

Edgeをいい感じに使えるようにする

背景

Chromium ベースの Edge が正式リリースされてから2年弱が経とうとしていますが、みなさんは Edge は使われていますか?
レガシー Edge のころはよく「Edge は Chrome をダウンロードする専用ブラウザ」みたいなことも言われていました。確かに自分も使い勝手やレンダリングの問題から使っていませんでした。
そんな中 MS が Chromium をベースとした新 Edge をリリースしました。新しい Edge はただ単にベースが変わっただけでなく、設定、プライバシー保護、タブの管理などかなり気合が入っており、特にビジネスで使う分には申し分ブラウザだと思います。
しかしながら最近 SNS で見かけた感じだと、あまり評価は変わらずといった印象を受けます。
本記事はそんな Edge のいいところ、設定次第で改善されるところを紹介していきたいと思います。

新 Edge のいけてるところ

  • Chromium ベースとなり、 Chrome と同等の動作が可能
  • Chrome拡張機能が利用可能
  • 設定画面がわかりやすい
  • プライバシー保護・セキュリティに関する設定が充実している
    • ラッキング防止の設定がわかりやすい
    • 利用状況の収集の許可が細かく設定可能
    • URL の typo や、悪意のあるサイトへのリダイレクトの検出

新 Edgeのいけてないところ

  • デフォルトの検索エンジンが Bing
  • 新しいタブを開いた時のホーム画面が重たい
  • 過剰なアピール
    • やめた方がいいと思う...
  • 個人で Chrome を使っていると Chrome から乗り換えるメリットが少ない
    • それはそう

いけてないところを改善する

既定の検索エンジンGoogle にする

  • 右上三点リーダーからメニューを開き、設定 を開きます。

f:id:tuki9ko:20211202121431p:plain:w400

  • プライバシー、検索、サービス をクリックし、一番下の アドレスバーと検索 をクリックします。

f:id:tuki9ko:20211202121749p:plain:w400
f:id:tuki9ko:20211202121752p:plain:w400

  • アドレスバーで使用する検索エンジンGoogle にします。
  • 新しいタブでの検索、検索ボックスまたはアドレスバーを使用するアドレスバー にして完了です。

f:id:tuki9ko:20211202121844p:plain:w400

ホーム画面のニュースを非表示にする

  • ホーム画面の歯車ボタンからメニューを開き、 カスタマイズ をクリックします。
  • 画面の表示内容ニュースを非表示 をクリックします。

f:id:tuki9ko:20211202122003p:plain:w400

画面レイアウトシンプルイメージ にしても下の方にニュースが出てきますので、完全に非表示にする場合は カスタマイズ にしてください。

私の Edge はこんな感じに

f:id:tuki9ko:20211202122030p:plain:w400

  • 検索バー、アドレスバーは共通で Google を使用する
  • ホーム画面はニュースを非表示にし、クイックリンクを2段にする
  • タブをたくさん開くので垂直タブバーを有効にする
  • ツールバーに履歴、Webキャプチャを表示する

おわりに

正直私は個人的な用途、ビジネス用途で使い分けてなくてごっちゃまぜにしてます...
メインは Chrome を使って、クリーンな環境(タブが散らかってないという意)で使いたいときとか、スポットな調べごとをするときは Edge を使ってます。

今メインで使っているのが Chrome の場合、確かにそこまで大きなメリットは無いと思います。例えばポリシー上個人アカウントと同期できない環境や、ソフトをインストールできないとき、動作確認や何やらでクリーンなブラウザが必要なときなどにぜひ利用してみてください!

Raspberry Pi 4 を WPA2-EAP なネットワークに繋ぐ

GUIで設定できなかったり、ググった内容が古かったりとかいろいろ苦労したのでメモ

環境

項目
ボード Raspberry Pi 4 Model B / 1GB
OS Raspbian GNU/Linux 10(Raspbian Buster)(Linux kernel 4.19.97-v7+)

設定の流れ

  • wpa_supplicant でアクセスポイントの認証情報の設定を行う。
  • dhcpcdIPアドレスの設定を行う。
  • 再起動する。

設定

WPA2-EAP の設定

wpa_supplicant の設定

設定ファイルは /etc/wpa_supplicant/wpa_supplicant.conf です。はじめに元に戻せるようにオリジナルをコピーしておきます。

cd /etc/wpa_supplicant
sudo cp wpa_supplicant.conf wpa_supplicant.conf.orig

コピー出来たら編集する前にパスワードをハッシュ化します。

read -s pass
(password入力)
echo -n "$pass" | iconv -t utf16le | openssl md4

出力された16バイトのハッシュ値クリップボードにコピーしておきます。 次に好きなエディタで /etc/wpa_supplicant/wpa_supplicant.conf を編集します。

vim wpa_supplicant.conf

以下を末尾に追記します。

network={
    ssid="<接続先のSSID>"
    proto=RSN
    key_mgmt=WPA-EAP
    pairwise=CCMP
    auth_alg=OPEN
    eap=PEAP
    identity="<ユーザー名>"
    password=hash:<パスワードハッシュ値>
    phase1="peaplabel=0"
    phase2="auth=MSCHAPV2"
    priority=1
}

各項目の説明に関しては下記の記事が参考になります。

qiita.com

パスワードのハッシュ化に関して

MD4を使用しているため、気休め程度にとらえておきましょう。環境によるところかもしれませんが、今回はNTLMで使用されるNTハッシュ(パスワードのUTF-16LE表現のMD4ハッシュ)でないといけないらしく、説明の通りとなっています。

IPアドレスの設定

IPアドレスの管理には dhcpcd というサービスが使われており、設定ファイルは /etc/dhcpcd.conf となります。
従来の設定ファイル /etc/network/interfaces は使用しません。

はじめに元に戻せるようにオリジナルをコピーしておきます。

cd /etc
sudo cp dhcpcd.conf dhcpcd.conf.orig

コピー出来たら編集していきます。

vim dhcpcd.conf

下記内容を末尾に追記します。

interface <無線LANインターフェース名>
env ifwireless=1
env wpa_supplicant_driver=wext,nl80211

静的IPアドレスを使用する場合はさらに下記内容を追記します。

static ip_address=<IPアドレス/CIDR>
static routers=<デフォルトゲートウェイIPアドレス>
static domain_name_servers=<DNSサーバIPアドレス>
static domain_search=<検索ドメイン>
noipv6

再起動

上記の設定を終えたら再起動します。

sudo reboot

躓いたところ

古い情報をもとに設定を行っていたところ、目的のネットワークに接続できるものの、DHCPサーバを見つけられずネットワークに参加できない状態になりました(リンクローカルアドレス(169.254.xxx.xxx)が割り当てられた状態)。その後 Raspbian Buster 向けの情報(dhcpcd.confの設定)を見つけて無事設定できました。

参考

qiita.com

forums.raspberrypi.com

unix.stackexchange.com

Laravel で Session Driver にデータベースを使用しているときに sessions スキーマを削除しちゃったときのやつ

TL;DR

sessions スキーママイグレーションファイルを作成してマイグレートするだけ

php artisan session:table
php artisan migrate

経緯

Session Driver にデータベースを使用している状態で、一度全部マイグレートしたくなって以下のコマンドを叩いた。

php artisan migrate:fresh
php artisan db:seed

すると自分で作成したテーブルは作成されたが、SESSIONSは作成されなかった。その結果ページを開くと下記のエラーが発生した。

SQLSTATE[42S02]: Base table or view not found: 1146 Table '[DB名].sessions' doesn't exist (SQL: select * from `sessions` where `id` = 6r7cK0x0tVcp6aKHLjei694lZcaWycKLrJ97nF3I limit 1)

解決方法

SESSIONS テーブルがないということなので、手動で作成する。

php artisan session:table
php artisan migrate

思ったこと

自分の環境はなんでマイグレーションファイルなかったんだろう……認証系のパッケージ入れたときに勝手に作成されたのかな……(結局使わずアンインストールした)

Laravel 開発メモ

基本的にはここの手順を追っています。

qiita.com

モデルの主キーで 'id' 以外を使いたい

qiita.com

モデルの主キーを文字列型にしたい

<?php

class Flight extends Model
{
    /**
     * IDが自動増分されるか
     *
     * @var bool
     */
    public $incrementing = false;
}

readouble.com

モデルに対応するテーブル名を変更したい

<?php

class Piyo extends Model
{
    /**
     * テーブル名
     *
     * @var string
     */
    protected $table = 'hogehoge';
}

created_at と updated_at の自動更新について

zenn.dev

created_at と updated_at は2038年問題を抱えているらしい

qiita.com

Laravel においてDDDのリポジトリ層を実装する

blog.shin1x1.com

REPL

qiita.com

コントローラへのルーティング

qiita.com

セッションの利用

qiita.com