趣味、研究、その他いろいろ

カテゴリー: LinuxServer(Ubuntu)

突然nginxが404 Not Foundになった件

起きた問題

私は自宅にWebサーバーを立ててブログサイトを建設しているのですが、ある日突然、「404 Not Found」となり、表示されなくなってしまいました。

systemctl restartしても変わりませんでした。

色々調べた結果

調べても、/etc/nginx/conf.d/配下にあるconfigファイルをいじる等の解決策は出てきましたが、私の場合は解決しませんでした。

解決方法

私の場合、一緒に動いているphp7.4-fpmの権限が原因でした。

$ sudo chmod 666 /run/php/php7.4-fpm.sock

と666にすることで直りました!

私のtmux.conf紹介

set -g default-terminal "screen-256color"
set -g terminal-overrides 'xterm:colors=256'

set -s escape-time 0

set-option -g status-interval 1

set -g base-index 1

setw -g pane-base-index 1

#set -g window-style 'bg=colour239'
#set -g window-active-style 'bg=colour234'

set -g prefix C-x

#bind - split-window -v

#bind \ split-window -h
bind-key \\ split-window -h
bind-key - split-window -v
# ペインの縦分割
#bind m split-window -vc "#{pane_current_path}"
# ペインの横分割
#bind n split-window -hc "#{pane_current_path}"

bind -n S-left select-pane -L
bind -n S-down select-pane -D
bind -n S-up select-pane -U
bind -n S-right select-pane -R

# Shift arrow to switch windows
bind -n C-Left  previous-window
bind -n C-Right next-window

bind -n C-o select-pane -t :.+

bind e setw synchronize-panes \; display "synchronize-panes #{?pane_synchronized,on,off}"

# Prefix+v でコピーモード開始
bind-key v copy-mode \; display "Copy mode!"
#bind-key -t vi-copy v begin-selection

# Prefix+p でペースト
# クリップボードにも保存されているので Cmd-v でもペースト可能
bind-key p paste-buffer

set-option -g status-justify "centre"

set-option -g status-bg "colour238"

set-option -g status-fg "colour255"

set-option -g status-left-length 20

set-option -g status-left "#[fg=colour255,bg=colour241]Session: #S #[default]"

set-window-option -g window-status-format " #I: #W "

set-window-option -g window-status-current-format "#[fg=colour255,bg=colour27,bold] #I: #W #[default]"

set-option -g status-right-length 60

set-option -g status-right "#[fg=colour255,bg=colour241] #h | LA: #(cut -d' ' -f-3 /proc/loadavg) | %m/%d %H:%M:%S#[default]"

set-option -g mouse on

bind -n WheelUpPane   select-pane -t= \; copy-mode -e \; send-keys -M
bind -n WheelDownPane select-pane -t= \;                 send-keys -M
#set-window-option -g mode-mouse on
#set-option -g mouse-select-window on
#set-option -g mouse-resize-pane on
#set-option -g mouse-select-pane on

cronが正しく送られない話

やりたいこと

Line Notifyを用いて定期的にリマインドしてくれるようにしたい

手順

Line Notifyのページ(こちら)からログインしてアクセストークンの発行(開発者向け)を行う。

Line notifyで通知してくれるシェルスクリプトを作成

自分は以下のように書きました。(リマインド:炊飯と通知してくれるコードです)

#!/bin/bash
LINE_ACCESS_TOKEN="jXN4lE38ve0ljxYRlF9jPBwytvcI48Xsad1iqRBKTeF"
function line_notify() {
  MESSAGE=$1
  curl -X POST -H "Authorization: Bearer ${LINE_ACCESS_TOKEN}" -F "message=$MESSAGE" https://notify-api.line.me/api/notify
}
line_notify "リマインド:炊飯"

これをcronに登録

$ echo "0 17 * * * . /home/itotaku/cron/notify_rice.sh" > cron.conf
$ crontab cron.conf

どこで詰まったか

直接

. /home/itotaku/cron/notify_rice.sh

とすれば通知できるのにcronを経由すると通知が来なかった。

Web検索しながら調べてみた

Webサイトで解決策を調べてみると、postfixのインストールが必要という記事をよく見ました。

それの通りにやってもうまくいかなかったです。

結局どう解決したか

根本的な問題の解決には至っていないかもしれませんが、シェルスクリプトに実行権限を与え、ドットコマンド(.)を使わずに登録すればうまくいきました。

$ chmod 775 notify_rice.sh
$ echo "0 17 * * * /home/itotaku/cron/notify_rice.sh" > cron.conf
$ crontab cron.conf

通知が来た!

let’s encriptの証明書の有効期限が切れたときの対処方法について

環境

Ubuntu20.04

nginx version: nginx/1.18.0 (Ubuntu)
built with OpenSSL 1.1.1f 31 Mar 2020

問題

let’s encriptのSSL証明書は3ヶ月であり、期限が切れてしまっていた。

有効期限が切れてしまうと

$ sudo certbot renew

をしてもうまくいかない。

解決策

有効期限が切れてしまった場合はまた1から証明書を作成する必要がある。

$ sudo certbot --nginx -d {ドメイン名}

と入力する。私のサイトでは

$ sudo certbot --nginx -d tsubame.0am.jp

となる。

証明書を作成したのに保護されない場合

良くある原因

まず良くある原因としてはnginxの設定ファイルで証明書のパスの指定が記述されていないことです。

設定ファイルの記述は/etc/nginx/conf.d/ssl.confに行います。

server {
    listen 443 ssl;
    server_name  tsubame.0am.jp www.tsubame.0am.jp;

    location / {
        root   /usr/share/nginx/html;
        index  index.php index.html index.htm;
    }

    ssl_certificate /etc/letsencrypt/live/tsubame.0am.jp/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/tsubame.0am.jp/privkey.pem;

    error_page  404  https://tsubame.0am.jp;

    error_page 500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    location ~ \.php$ {
        try_files $uri =404;
        root           /usr/share/nginx/html;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_script_name;
        include fastcgi_params;
    }
    location ^~ /index.html {
      return 301 http://tsubame.0am.jp/itotakublog/index.php$query_string;
    }
}

server {
    # httpをhttpsにリダイレクト
    listen 80;
    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl;
    # SSLを無効化してTLSのみ受け付ける
    ssl_protocols  TLSv1.2 TLSv1.3;
}

私の場合

私のサイトではURLが間違っていた場合、全てホームページにリダイレクトするようにしているのですが、その時に80ポートもリッスンしているとhttpの方にリダイレクトされてしまうことがあるみたいです。

よって/etc/nginx/conf.d/ssl.conf

listen 80

をコメントアウトすることで解決できました。

Pytorchを用いたCNNサンプルコード

# -*- coding: utf-8 -*-
import sys, os
import torch
import numpy as np
import torch.nn.functional as F
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
from torch.utils.data.sampler import SubsetRandomSampler
import matplotlib.pyplot as plt
import torch.nn as nn
import time
from tqdm import tqdm
MODEL_PATH = "CNNmodel.pth.tar"
MODEL_SAVE_PATH = "CNNmodel_normal.pth.tar"

def load_cifar10(batch=128):
    num_workers = 4
    valid_size = 0.2
    train_data = datasets.MNIST(root = 'data', train = True, download = True, transform = transforms.Compose([ transforms.ToTensor()]))
    test_data = datasets.MNIST(root = 'data', train = False, download = True, transform = transforms.Compose([ transforms.ToTensor()]))

    num_train = len(train_data)
    indices = list(range(num_train))
    np.random.shuffle(indices)
    # trainとvalidの境目(split)を指定
    split = int(np.floor(valid_size * num_train))
    train_index, valid_index = indices[split:], indices[:split]

    # samplerの準備
    train_sampler = SubsetRandomSampler(train_index)
    valid_sampler = SubsetRandomSampler(valid_index)
    # data loaderの準備
    train_loader = torch.utils.data.DataLoader(train_data, batch_size = batch,
                                               sampler = train_sampler, num_workers = num_workers)
    valid_loader = torch.utils.data.DataLoader(train_data, batch_size = batch,
                                              sampler = valid_sampler, num_workers = num_workers)
    test_loader = torch.utils.data.DataLoader(test_data, batch_size = batch,
                                             num_workers = num_workers)

    return {'train_loader': train_loader, 'valid_loader': valid_loader, 'test_loader': test_loader}

class MyCNN(torch.nn.Module):
    def __init__(self):
        super(MyCNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, 5)  # 28x28x1 -> 24x24x32
        self.pool = nn.MaxPool2d(2, 2)  # 24x24x32 -> 12x12x32
        self.dropout1 = nn.Dropout2d(0.2)
        self.conv2 = nn.Conv2d(32, 64, 5)  # 12x12x32 -> 8x8x64
        self.dropout2 = nn.Dropout2d(0.2)
        self.fc1 = nn.Linear(8 * 8 * 64, 128)
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):  # predictに相当(順伝搬)
        x = self.pool(F.relu(self.conv1(x)))
        x = F.relu(self.conv2(x))
        x = self.dropout1(x)
        x = x.view(-1, 8 * 8 * 64)
        x = F.relu(self.fc1(x))
        x = self.dropout2(x)
        x = self.fc2(x)
        return x

def save_checkpoint(state, filename):
    torch.save(state, filename)

def train():
    print("will begin training")
    flag_70=False
    flag_99=False
    for ep in range(epoch):
        train_loss_total = 0
        train_acc_total = 0
        valid_loss_total = 0
        valid_acc_total = 0
        net.train()
        loss = None
        for i, (images, labels) in enumerate(loader['train_loader']):
            # viewで28×28×1画像を1次元に変換し、deviceへ転送
            images, labels = images.to(device), labels.to(device) # そのまま使う
            optimizer.zero_grad()  # 勾配リセット
            outputs = net(images)  # 順伝播の計算
            loss = criterion(outputs, labels)  # lossの計算
            train_loss_total += loss.item()  # train_loss に結果を蓄積
            acc = (outputs.max(1)[1] == labels).sum()  # 予測とラベルが合っている数の合計
            train_acc_total += acc.item()  # train_acc に結果を蓄積
            loss.backward()  # 逆伝播の計算
            optimizer.step()  # 重みの更新
            if i % 10 == 0:
                print('Training log: {} epoch ({} / 50000 train. data). Loss: {}, Acc: {}'.format(ep + 1,
                                                                                         (i + 1) * 128,
                                                                                         loss.item(),
                                                                                         acc)
                      )

        torch.save(net.state_dict(), MODEL_SAVE_PATH)
        train_loss = train_loss_total / len(loader['train_loader'].sampler)
        train_acc = train_acc_total / len(loader['train_loader'].sampler)

        history['train_loss'].append(train_loss)
        history['train_acc'].append(train_acc)

        net.eval()
        correct = 0
        with torch.no_grad():
            for i, (images, labels) in enumerate(tqdm(loader['valid_loader'])):
                # viewで28×28×1画像を1次元に変換し、deviceへ転送
                images, labels = images.to(device), labels.to(device)  # そのまま使う
                outputs = net(images) # 出力を計算(順伝搬)
                loss = criterion(outputs, labels) # lossを計算
                valid_loss_total += loss.item() # lossを足す
                acc = (outputs.max(1)[1] == labels).sum() # 正解のものを足し合わせてaccを計算
                valid_acc_total += acc.item() # accを足す

        valid_loss = valid_loss_total / len(loader['valid_loader'].sampler)
        valid_acc = valid_acc_total / len(loader['valid_loader'].sampler)
        history['valid_loss'].append(valid_loss)
        history['valid_acc'].append(valid_acc)
        print("valid_acc=",valid_acc)
        if valid_acc>=0.7 and flag_70==False:
            print("70%over")
            flag_70=True
            torch.save(net.state_dict(), 'CNNmodel_checkpoint_70.pth.tar')
        elif valid_acc>=0.99 and flag_99==False:
            print("99%over")
            flag_99=True
            torch.save(net.state_dict(), "CNNmodel_checkpoint_99.pth.tar")

def test():
    test_loss_total = 0
    test_acc_total = 0
    total = 0
    class_correct = list(0. for i in range(10))
    class_total = list(0. for i in range(10))
    net.eval() # ネットワークを推論モードへ
    with torch.no_grad():
        for i, (images, labels) in enumerate(tqdm(loader['test_loader'])):
            images, labels = images.to(device), labels.to(device)
            outputs = net(images)
            loss = criterion(outputs,labels) # 損失を計算
            # 出力と結果が一致している個数を計算
            _,pred = torch.max(outputs,1)
            test_acc_total += np.squeeze(pred.eq(labels.data.view_as(pred)).sum())
            total += labels.size(0)
            test_loss_total += loss.item()*images.size(0)
            c = (pred == labels).squeeze()
            for i in range(4):
                label = labels[i]
                class_correct[label] += c[i]
                class_total[label] += 1

    test_loss = test_loss_total / len(loader['test_loader'].sampler)
    test_acc = test_acc_total.item() / len(loader['test_loader'].sampler)
    history['test_loss'].append(test_loss)
    history['test_acc'].append(test_acc)

    print('Accuracy of the network on the 10000 test images: %d %%' % (
        100 * test_acc_total.item() / total))
    for i in range(10):
        print('Accuracy of %5s : %2d %%' % (
            classes[i], 100 * class_correct[i] / class_total[i]))

def plot():
    # 結果をプロット
    plt.figure()
    plt.plot(range(1, epoch+1), history['train_loss'], label='train_loss', color='red')
    plt.plot(range(1, epoch+1), history['valid_loss'], label='val_loss', color='blue')
    plt.title('CNN Training Loss [CIFAR10]')
    plt.xlabel('epoch')
    plt.ylabel('loss')
    plt.legend()
    plt.savefig('img/CNN_loss.png')

    plt.figure()
    plt.plot(range(1, epoch+1), history['train_acc'], label='train_acc', color='red')
    plt.plot(range(1, epoch+1), history['valid_acc'], label='val_acc', color='blue')
    plt.title('CNN Accuracies [CIFAR10]')
    plt.xlabel('epoch')
    plt.ylabel('accuracy')
    plt.legend()
    plt.savefig('img/CNN_acc.png')
    plt.close()

if __name__ == '__main__':
    start = time.time()
    epoch = 10
    loader = load_cifar10()
    classes = ('plane', 'car', 'bird', 'cat', 'deer',
               'dog', 'frog', 'horse', 'ship', 'truck')  # CIFAR10のクラス
    torch.backends.cudnn.benchmark=True
    use_cuda=torch.cuda.is_available()
    if use_cuda:
        device = 'cuda'
    else:
        device = 'cpu'
    print("device=",device)
    net: MyCNN = MyCNN().to(device)
    criterion = torch.nn.CrossEntropyLoss()  # ロスの計算
    optimizer = torch.optim.SGD(params=net.parameters(), lr=0.01, momentum=0.9,weight_decay=0.00005)
    flag = os.path.exists(MODEL_PATH)
    if flag: #前回の続きから学習
        print('loading parameters...')
        source = torch.load(MODEL_PATH, map_location=lambda storage, loc: storage)
        net.load_state_dict(source)
        print('parameters loaded')
    else:
        print("途中のパラメータなし")

    history = {
        'train_loss': [],
        'train_acc': [],
        'valid_loss': [],
        'valid_acc': [],
        'test_loss': [],
        'test_acc': []
    }
    train()
    test()
    if flag == False:
        plot()
    elapsed_time = time.time() - start
    print ("elapsed_time:{0}".format(elapsed_time) + "[sec]")
cycler==0.10.0
dataclasses==0.6
future==0.18.2
kiwisolver==1.3.1
matplotlib==3.3.3
numpy==1.19.4
Pillow==8.0.1
pyparsing==2.4.7
python-dateutil==2.8.1
six==1.15.0
torch==1.7.0+cu110
torchaudio==0.7.0
torchvision==0.8.1+cu110
tqdm==4.52.0
typing-extensions==3.7.4.3

SSDの容量が何故か少ない!

今回はSSDの容量が合っていない時の私が直面した問題とその対処法についてご紹介します。

問題の状況

私は1TBのm.2SSDを購入して自作pcに挿入して使っています。

UbuntuにはUbuntu DesktopとUbuntu Serverがあります。

Ubuntu Desktopは普通に自作pcをパソコンとして使いたい人向け

Ubuntu Serverは自作pcをサーバーとして使いたい人向けです。

ちなみにServerとDesktop両方入れることもでき、その場合は最初にServerを入れてからDesktopを入れた方が遙かに楽だと思います。

無知な私はServerを入れたいのに間違ってDesktopを入れてしまいました。(これを間違えなかったら以下の問題は発生しなかったかもしれません。)

その後Ubuntu Serverを再度インストールしてServer内で

df -h

コマンドで見ると

Filesystem                         Size  Used Avail Use% Mounted on
udev                                16G     0   16G   0% /dev
tmpfs                              3.2G  2.1M  3.2G   1% /run
/dev/mapper/ubuntu--vg-ubuntu--lv  196G   36G  151G  20% /
tmpfs                               16G     0   16G   0% /dev/shm
tmpfs                              5.0M  4.0K  5.0M   1% /run/lock
tmpfs                               16G     0   16G   0% /sys/fs/cgroup
/dev/nvme0n1p2                     976M  244M  665M  27% /boot
/dev/nvme0n1p1                     511M  7.8M  504M   2% /boot/efi
/dev/loop0                          55M   55M     0 100% /snap/core18/1880
/dev/loop1                          56M   56M     0 100% /snap/core18/1932
/dev/loop3                          30M   30M     0 100% /snap/snapd/8542
/dev/loop2                          68M   68M     0 100% /snap/lxd/18150
/dev/loop4                          72M   72M     0 100% /snap/lxd/16099
/dev/loop5                          31M   31M     0 100% /snap/snapd/9721
tmpfs                              3.2G   20K  3.2G   1% /run/user/122
tmpfs                              3.2G   24K  3.2G   1% /run/user/1000

1TBのm.2SSDが196GBしかありません。

解決策の前に一つ

今回直面した問題の解決策を理解するにはLVM(Logical Volume Management)という概念を理解しなければいけません。(知ってるよ!という方は読み飛ばしてください)

今回の問題で使う部分のみ説明を行うと

1Tバイトのある「物理ボリューム」というSSD上のパーティションがあり、これを複数の「論理ボリューム」という仮想のパーティションに分けています。

私の場合はUbuntu Serverに使われていた「論理ボリューム」が196Gバイトしかなかったということになります。(残りの約800Gバイトは別の論理ボリュームに割り当てられているト考えられます。)

m.2SSDの容量を全て使いたい!と思うと思います。

LVMには様々なコマンドがあって上記のことももちろんできます。

以下に私の場合の解決策を提示したいと思います。

解決策

私の場合は「Serverの論理ボリュームを全ての空き容量に拡張して使う」ということです。

論理ボリュームの拡大には「lvextend」コマンド

全ての空き容量を使うには「+100%FREE」オプションを使います。

私の場合は1TBの物理ボリュームが入っているubuntu-vgという物理ボリュームの集まり(ボリュームグループ)があり、

そこに含まれる論理ボリュームを拡張したいので

lvextend -l +100%FREE ubuntu-vg/ubuntu-lv

これで

itotaku@anubis:~$ df -hT
Filesystem                        Type      Size  Used Avail Use% Mounted on
udev                              devtmpfs   16G     0   16G   0% /dev
tmpfs                             tmpfs     3.2G  2.1M  3.2G   1% /run
/dev/mapper/ubuntu--vg-ubuntu--lv ext4      915G   36G  840G   5% /
tmpfs                             tmpfs      16G     0   16G   0% /dev/shm
tmpfs                             tmpfs     5.0M  4.0K  5.0M   1% /run/lock
tmpfs                             tmpfs      16G     0   16G   0% /sys/fs/cgroup
/dev/nvme0n1p2                    ext4      976M  244M  665M  27% /boot
/dev/nvme0n1p1                    vfat      511M  7.8M  504M   2% /boot/efi
/dev/loop0                        squashfs   55M   55M     0 100% /snap/core18/1880
/dev/loop1                        squashfs   72M   72M     0 100% /snap/lxd/16099
/dev/loop2                        squashfs   68M   68M     0 100% /snap/lxd/18150
/dev/loop3                        squashfs   30M   30M     0 100% /snap/snapd/8542
/dev/loop4                        squashfs   56M   56M     0 100% /snap/core18/1932
/dev/loop5                        squashfs   31M   31M     0 100% /snap/snapd/9721
tmpfs                             tmpfs     3.2G   16K  3.2G   1% /run/user/122
tmpfs                             tmpfs     3.2G   24K  3.2G   1% /run/user/1000

915GB(約1T)になってる!

皆さんも

df-h

結果に「~~vg」や「~~lv」等があったらLVMを疑ってみてください!

他にもLVMにはたくさんコマンドがあります。それらは上記のリンクを参照してください。

AmpereのGPUでPyTorchを動かすときに詰まった話

こちらはrioyokotalab Advent Calendar 2020の10日目の記事です

本題に入る前にちょっと雑談

上にあるリンクは研究室で行われているアドベントカレンダーです。研究室でブログを書いていこう!という企画だそうです。

こちらに参加しようと思った時に、自分はブログを書いたことがなく、どのように書いていくかもわからない。。そんな感じでした。

そんな時、サーバーを持っているじゃないか。。サーバーをレンタルすることもない!そんなこともありWebサーバーを立て、ブログサイトを立ち上げてみることにしました!そうしてできたのがこのサイトです。

AmpereGPUとは

NvidiaのGPUは大きく分けてKeplar,Maxwel Pascal,Volta,Turing,Ampereに分かれています。

XX50XX60XX70XX80XX90
Keplar750760770780
Maxwel950960970980
Pascal1050106010701080
Turing206020702080
Ampere307030803090
Nvidia GPU

下に行けば行くほど新しく、右に行けば行くほど性能はいいという感じです。

TuringのGPUには2050Ti、2080Tiといった”Ti”が付くものや、20XXSUPER といった”SUPER”が付くものがあり、これらはどちらも付いていないGPUよりも少し性能が良くなっています。

今回は一番下の現在新しいGPU(Ampere)において詰まった話をご紹介します。

これ、遅くない?と思ったきっかけ

自分のサーバーにはRTX3070を積んでいるのですが、自分にはpascalの1080Tiという1080よりも少し性能が良くなったGPUと、V100という一つ100万くらいするめちゃくちゃ高いGPUを使える環境がありました。

1GPUでの実験は基本的に自分のサーバーでやっていたのですが、、、

ある時、1080Ti、V100でも動かしてみようと思い、動かした結果。。

(ちなみに動かしているサンプルコードはCIFAR10をResnet18で1epochだけ学習するものです。)

GPU時間
V100約5秒
1080Ti約8秒
3070約26秒
あるプログラムの実行にかかった時間

ん???????

V100は3070よりも古いですがお値段が相当高い、とても高価なGPUなのでまあ早いのはわかります。

しかし、1080Tiと比べて3070が3倍以上時間がかかっているのは明らかにおかしい!!!

色々調べてみる

gemmを実行してみる

そもそもGPUの性能を発揮できているのか?と思い、https://github.com/enp1s0/gpu_perf のコードを借りてGPUのパフォーマンスを出力してみた結果。

GPUパフォーマンス
1080Ti1.072296e+01 [TFlop/s]
30701.312955e+01 [TFlop/s]
GPUのパフォーマンス

しっかり3070の方が性能が出ています。

ちなみにResnet18をはじめ、畳み込み層を計算するためにはcuDNNのインストールが必要になりますが、こちらはpytorchのインストールの際に自動で入るそうです。

プロファイラをとってみる

ubuntu serverではnsysコマンドを用いてプロファイラをとることができます。

こちらを1080Tiと3070で取ってみました

3070ではcuBLAS GEMMが全体の実行時間の50%を占めている状況

1080Tiではwinogradが全体の17%を占めている状況

という感じでした。ちなみに3080を持っている方にプログラムをお渡しして実行していただいても1080Tiよりは遅いという結果でした。

結局何が原因だったの?

結論から言うとPyTorchのサンプルコードに

torch.backends.cudnn.benchmark = True

この1行を埋め込むだけで3070だけ異常に速くなりました。

GPU時間
V100約5秒
1080Ti約8秒
3070約5.5秒
あるプログラムの実行にかかった時間

しっかり、PascalGPUよりは性能が出ていますね。V100と1080Tiは大きな変化は見られなかったです。

なぜこんなことが起きたかというとはっきりした原因はわかりませんが、

torch.backends.cudnn.benchmark = True

というのは畳み込みアルゴリズムを総当たりで探索するかどうかを設定するものです。

おそらく、AmpereGPUは新しいため、まだPyTorchに100%対応しておらず、デフォルトのアルゴリズムが遅いのでは?という結論に至りました。

新しすぎてもPyTorch側が対応していないとこんなにも遅くなってしまうのですね。。。。

wordpressにログインしようとしたらリダイレクトループ!!

wordpressにログインしようとしたらまた、ログイン画面に戻される。。。。

この繰り返しをリダイレクトループといいます。自分の場合はさらにログイン画面のデザインもおかしかったです。

こういうバグってどこでエラーが起きてるかってわかりにくいですよね。

普通は

/var/log

を見に行くと思うのですがwordpressならnginxやphp等の下で動いているのでそれらがエラーを出していないか等すべてログファイルを見に行かなければなりません。

今回の場合はどこのログにもエラーは載っていませんでした。

自分が解決できた方法

原因はwordpressフォルダ直下にあるwp-config.phpの記述の間違いでした。

wordpressをインストールした際にwp-config.phpに色々コードを加えたと思うのですがそちらを加える位置に問題がありました。wp-config.phpをよく見てみると、、、、

/* That's all, stop editing! Happy publishing. */

と書いてある行があると思います。この行より下は基本的にいじったりコードを追加したりしてはいけません!

ここより下にあるコードをすべて上にもってきたらデザインも直り、ログインのリダイレクトループも解消されました!

要するにちゃんと英語を読みましょうという話です。

さらに同じ変数の定義を2回以上しているとこれもまたリダイレクトループの原因となります。(様々なサイトからコピペしている方要注意!)