TensorFlowを利用するWSGIサーバの構築に向けたPython3環境の構築（続・Ubuntu編）

## 記述を行うところの動機
+ 前回の記事を補足したかった
+ 環境作成作業自体が混沌としていたので、実際の稼働に対する担保が取りづらくなっていた
+ 特に、pip3によるインストールでのインストールする必要なライブラリについては、明記する必要があった
+ 動くサンプルを提供しなければ、と思い込むタイプなので

## 前提
* OS：Ubuntu 24.04 LTS
* Python: version python-3.9.18
* Chat-GPT API：GPT-4V

## 環境作成

### OSのインストール
下記リンクを参考にしてください。

[Ubuntuを入手する](https://jp.ubuntu.com/download)

### OSのアップデート
こちらも行いましょう。
```
sudo apt update
sudo apt upgrade
```

### WSGIサーバのインストール
Apache です。
```
sudo apt install apache2
```

WSGI環境構築につきましては、前回の記事にリンクがありますので、参照ください。

https://qiita.com/hashimotonet/items/8327654449fd54a33e03

## ここから本番です
### 必要なライブラリのインストール
```
$ sudo apt install build-essential
```
```
$ sudo apt install libbz2-dev libdb-dev libreadline-dev \
  libffi-dev libgdbm-dev liblzma-dev libncursesw5-dev \
  libsqlite3-dev libssl-dev zlib1g-dev \
  uuid-dev tk-dev
```

### OpenSSLのインストール
```
$ cd /usr/local/src
$ wget https://www.openssl.org/source/openssl-3.0.7.tar.gz
$ sudo tar xvzf openssl-3.0.7.tar.gz
$ cd openssl-3.0.7
$ sudo ./Configure
$ sudo make
$ sudo make install
```

### bzip2のインストール
```
$ cd /usr/local/src
$ sudo git clone https://git.code.sf.net/p/bzip2/bzip2 bzip2-bzip2
$ cd bzip2-bzip2
$ sudo make
$ sudo make install
```

### sqlite3 のインストール
```
$ cd /usr/local/src
$ sudo wget https://www.sqlite.org/2024/sqlite-autoconf-3450300.tar.gz
$ sudo tar -xvzf sqlite-autoconf-3450300.tar.gz
$ cd sqlite-autoconf-3450300
$ ./configure
$ make
$ sudo make install
```

## Python3.9.18のmakeとインストール
### 
インストール時に必要な設定。
```
$ export CFLAGS="-I/usr/include/openssl -L/usr/local/src/bzip2-bzip2" 
$ export LDFLAGS="-L/usr/local/lib -L/usr/local/lib -L/usr/local/lib -L/usr/local/bin/sqlite3 -L/usr/local/lib" 
$ export LD_RUN_PATH=/usr/local/lib:/usr/lib:/usr/lib64
$ export LD_LIBRARY_PATH=/usr/local/lib:/usr/lib:/usr/lib64
$ export PKG_CONFIG_PATH=/usr/lib/pkgconfig
$ export OPENSSL_LDFLAGS=-L/usr/include/openssl
$ export OPENSSL_INCLUDES=-I/usr/include/openssl
```

```
$ cd /usr/local/src
$ sudo wget https://www.python.org/ftp/python/3.9.18/Python-3.9.18.tgz
$ sudo tar xvzf Python-3.9.18.tgz
$ cd Python-3.9.18
```

```
$ vi Modules/Setup
```

下記を参考に214～217行目をコメント解除。
```
    212 # Socket module helper for SSL support; you must comment out the other
    213 # socket line above, and possibly edit the SSL variable:
    214 SSL=/usr/local/ssl
    215 _ssl _ssl.c \
    216         -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
    217         -L$(SSL)/lib -lssl -lcrypto
```

下記を順次実行する。
```
$ ./configure \
--with-ensurepip \
--enable-shared \
--enable-ipv6 \
--with-openssl=/usr/local/ssl \
--enable-optimizations \
--enable-threads \
--prefix=/usr/local/python-3.9.18 \
--with-system-ffi=/usr/local/lib64 \
--enable-loadable-sqlite-extensions \
--with-openssl-rpath=auto \
--with-openssl=/usr/local/src/openssl-3.0.7 \
$ sudo make -j 8
$ sudo make altinstall
```

~/.bashrc の末尾に以下の追記を行う。
```
export LD_LIBRARY_PATH=/usr/local/lib64:/usr/lib:/usr/lib64
```

## pip でインストールを行うライブラリについて
後述するソースは、今回環境用に前回のものに対して若干の修正を行っている。
稼働を行うには、次に掲げるライブラリをインストールする必要がある。

なお、下記より登場する「python3.9」は、今回インストールした python3.9.19 を呼ぶコマンドである。

まず、pipを最新化する。
```
$ wget https://bootstrap.pypa.io/get-pip.py
$ python3.9 get-pip.py
$ python3.9 -m pip install --upgrade pip
```

本命のTensorFlowのインストール。下記で、バージョンの確認も行いたい。
```
$ pip3.9 install tensorflow==2.16.1 tensorRT
$ python3.9 -c "import tensorflow as tf; print( tf.__version__ )"
```

後述するソースの稼働において必要となるライブラリをインストール。
```
$ pip3.9 install Flask
$ pip3.9 install Image
$ pip3.9 install pyyaml
$ pip3.9 install h5py
```

# 今回稼働を確認したソース
前回のものから修正したもの。当初は稼働できなかった。環境面での差異によるものと思われる。

```python:App_02.py
#!/usr/local/python-3.9.18/bin/python3.9
# -*- coding: utf-8 -*-
import sys
sys.path.append('')
sys.path.append('/home/hashimotonet/.local/lib/python3.9/site-packages')

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import models
from flask import Flask, request, jsonify
from tensorflow.keras.models import save_model as saver
from tensorflow.keras.models import load_model as loader
import os
from PIL import Image
import numpy as np

app = Flask(__name__)

# 下記と同名のフォルダを、実行環境と同一の階層に作成する
UPLOAD_FOLDER = 'uploads/'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

# ディレクトリを作成
os.makedirs('models', exist_ok=True)

# モデルの入力形状を定義
input_shape = (1, 784)
input_layer = keras.layers.Input(shape=input_shape)

# 後続のレイヤーを追加
x = keras.layers.Dense(128, activation='relu')(input_layer)
x = keras.layers.Dropout(0.2)(x)
output_layer = keras.layers.Dense(10, activation='softmax')(x)

# モデルの作成
model = models.Model(inputs=input_layer, outputs=output_layer)
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# モデルを保存
saver(model, 'models/my_model.h5')

# 保存されたモデルの読み込み
gpt4_model = loader('models/my_model.h5')

@app.route('/flask/upload', methods=['POST'])
def upload_file():
    if 'image' not in request.files:
        return "No file part", 400
    file = request.files['image']
    if file.filename == '':
        return "No selected file", 400

    filepath = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)
    file.save(filepath)

    # 画像を前処理し、モデルに入力
    processed_image = process_image(filepath)
    result = call_gpt4(processed_image)

    # ファイルを削除
    os.remove(filepath)

    # JSON値を返却
    return jsonify(result)

def process_image(filepath):
    image = Image.open(filepath).convert('L')  # グレースケールに変換
    image = image.resize((28, 28))            # (28, 28) サイズにリサイズ
    image_array = np.array(image)
    image_array = image_array / 255.0          # 正規化
    image_array = image_array.flatten()        # フラットに変換
    image_array = np.expand_dims(np.expand_dims(image_array, axis=0), axis=1)  # (1, 784) に変換
    return image_array

def call_gpt4(image_array):
    # モデルの予測を呼び出し
    predictions = gpt4_model.predict(image_array)
    response = {"predictions": predictions.tolist()}  # 必要に応じて変換
    return response

if __name__ == '__main__':
    app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024  # 最大16MBのファイルサイズを許可
    app.debug = True
    app.run()
```

## 実行
運用は、WSGI環境にて行っていただきたい。
ここでは手短に、下記で紹介するコマンドで稼働を確認する。
```
python3.9 App_02.py
```
```
curl -X POST -F image=@/usr/share/backgrounds/Fuji_san_by_amaral.png http://localhost:5000/flask/upload
```

今回はここまでです。次はAWSのAmazon Linux2023上にて環境を作成する予定です。