背景
ChatGPTには、画像アップロード機能が加わり、画像解析を行う機能が追加されたことを知ることになった。
画像ストアサービス【PhotoGallery(osm.yokohama)】を運営する身としては、垂涎ものである機能と思い、早速WebAPI経由で接続をすることを試したくなった。
そんな中、ChatGPTの中で、文章末尾にあるソースの提示を受ける。ありがたや、ありがたや。
前提
OS: Amazon Linux 2
Python: version python-3.9.18
Apache Web Server version: Apache/2.4.59
TensorFlowは、以下のスレッドで問題に上がっているようなことがあるため、Pythonバージョンを指定する必要がある
また、pyenv からの実行環境のインストールは、OpenSSL関連でつまづいたので、ソースからインポートする必要があった。
必要なライブラリをまずインストール
$ sudo yum install libffi-devel
$ sudo yum install perl
$ sudo yum install perl-IPC-Cmd
$ sudo yum install perl-Test-Simple
$ sudo yum install zlib-devel
$ sudo yum install bzip2-devel
$ sudo yum install ncurses-devel
$ sudo yum install libffi-devel
$ sudo yum install libuuid libuuid-devel
$ sudo yum install sqlite-devel
$ sudo yum install readline-devel
$ sudo yum install tk-devel
opensslのインストール
リンク先を参考に、opensslの適切なバージョンをインストールする。
openssl環境
$ openssl version -a
当方環境の場合
OpenSSL 3.1.2 1 Aug 2023 (Library: OpenSSL 3.1.2 1 Aug 2023)
built on: Mon Jun 24 18:31:19 2024 UTC
platform: linux-x86_64
options: bn(64,64)
compiler: gcc -fPIC -pthread -m64 -Wa,--noexecstack -Wall -O3 -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_BUILDING_OPENSSL -DNDEBUG
OPENSSLDIR: "/usr/local/ssl"
ENGINESDIR: "/usr/local/lib64/engines-3"
MODULESDIR: "/usr/local/lib64/ossl-modules"
Seeding source: os-specific
CPUINFO: OPENSSL_ia32cap=0xfffa3203478bffff:0x7a9
インストール時に必要な設定(前途のopensslコマンドの出力などに合わせる)
$ export CFLAGS="-I/usr/include/openssl -L/usr/local/src/bzip2-1.0.8"
$ export LDFLAGS="-L/usr/local/lib64 -L/usr/local/lib -L/usr/local/lib64 -L/usr/share/tcl8.5/sqlite3 -L/usr/local/lib64"
$ export LD_RUN_PATH=/usr/local/lib64:/usr/local/lib:/usr/lib:/usr/lib64
$ export LD_LIBRARY_PATH=/usr/local/lib64:/usr/local/lib:/usr/lib:/usr/lib64
$ export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
$ export OPENSSL_LDFLAGS=-L/usr/include/openssl
$ export OPENSSL_LIBS=-l/usr/lib64/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
[Modles/Setup]ファイルの編集
$ vi Modules/Setup
206~209行目をコメント解除(行番号はオプションで表示)
204:# Socket module helper for SSL support; you must comment out the other
205:# socket line above, and possibly edit the SSL variable:
206:SSL=/usr/local/ssl
207:_ssl _ssl.c \
208: -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
209: -L$(SSL)/lib -lssl -lcrypto
ここまでで何度かつまづいている場合には、以下を実行しましょう。
$ sudo make clean
実行
$ ./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.1.2
$ sudo make -j 8
$ sudo make altinstall
また下記を行う
$ ln -s /usr/local/python-3.9.18/lib/libpython3.9.so.1.0 /usr/local/lib64/libpython3.9.so.1.0
$ export LD_LIBRARY_PATH=/usr/local/lib64:/usr/lib64
結果としてのPyCMethod_Newに関する定義
$ readelf -s /usr/local/src/Python-3.9.18/libpython3.9.so | grep "PyCMethod"
419: 0000000000227a70 775 FUNC GLOBAL DEFAULT 11 PyCMethod_New
1657: 00000000007c8f00 408 OBJECT GLOBAL DEFAULT 23 PyCMethod_Type
9888: 00000000008c2ba0 48 OBJECT LOCAL DEFAULT 24 __gcov0.PyCMethod_GetClas
9889: 00000000008c2b88 8 OBJECT LOCAL DEFAULT 24 __gcov7.PyCMethod_GetClas
9896: 00000000008c2a00 8 OBJECT LOCAL DEFAULT 24 __gcov7.PyCMethod_New
9897: 00000000008c2a20 160 OBJECT LOCAL DEFAULT 24 __gcov0.PyCMethod_New
9949: 00000000007c8520 72 OBJECT LOCAL DEFAULT 23 __gcov_.PyCMethod_GetClas
9953: 00000000007c83a0 72 OBJECT LOCAL DEFAULT 23 __gcov_.PyCMethod_New
29548: 0000000000227750 202 FUNC LOCAL DEFAULT 11 PyCMethod_GetClass
30142: 0000000000227a70 775 FUNC GLOBAL DEFAULT 11 PyCMethod_New
31269: 00000000007c8f00 408 OBJECT GLOBAL DEFAULT 23 PyCMethod_Type
インストールされたtensor関連ライブラリはこちら
$ pip list | grep tensor
tensorboard 2.16.2
tensorboard-data-server 0.7.2
tensorflow 2.16.1
tensorflow-estimator 2.15.0
tensorflow-io-gcs-filesystem 0.37.0
tensorrt 8.5.2.2
参考
AWS EC2(Amazon Linux 2)サーバー に Apache2.4, Python3, wsgiの実行環境を構築する
Python3.xをインストール(ソースからビルド)for RockyLinux 9.x
実行サーバのソース
$ python3 App.py
Pythonがインストールできており、ライブラリが完備されていれば*上記コマンドでも、実行は可能だ。ただし、実行ログで
開発のみに使用すべきであって、製品として使用するにはWSGI環境で実行してください
と言われるので、リンク先のサイトを参考に、環境を構築することとしてください。
最後に、提供を受けたものですが、アップロード対象サーバ及びGPT-4 に接続し、画像解析を行う(開発中ですが...)ソースを掲載します。
#!/usr/local/python-3.9.18/bin/python3.9
# -*- coding: utf-8 -*-
import sys
sys.path.append('')
sys.path.append('/home/ec2-user/.local/lib/python3.9/site-packages')
import tensorflow as tf
from flask import Flask, request, jsonify
import os
from PIL import Image
import numpy as np
app = Flask(__name__)
# 下記と同名のフォルダを、実行環境と同一の階層に作成する
UPLOAD_FOLDER = 'uploads/'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
# 保存されたモデルの読み込み
gpt4_model = tf.keras.models.load_model('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(image_array, axis=0) # (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()
※ソース冒頭で実行環境のPythonのパスを記述している(今回はTensorFlowの使用を行い、前途のリンクにもある理由があるため、Pythonのバージョンはこれである必要がある)
※必要なライブラリに関しては pip コマンドにてインストールすること。
雑感・あとがき
上記実行サーバソースに対して、
curl -X POST -F image=@166.jpg http://localhost:5000/flask/upload
のようなコマンド(送信ファイル名は任意)を送信したところの返却される値とは、小数点以下を多く持つ数値の配列である。
なので下記。
画像を解釈可能なフォーマットにして、解析すること。機械がそれを行う起点となることは、特徴を数値に変換することである。今回はそこまでが取得できるだけの成果にとどまっている。
人工でない頭脳は、経験に基づき「画像が何であるのか」について、あらゆる角度から判定を行っている。
そのことに近付くことが、どれだけのステップを踏むことになるのか想像するのは容易でない。ただしそのスタート地点に立っている試みが始まっていることが確認できたことは、成果と言えると思っている。
以上です。