So I’ve been trying to implement a fastai model into a Flask model on Google Cloud Platform, but I keep having issues with my exported model since I built my model on Windows. Note that I’ve tried to use the work around that exists for converting between PosixPaths and WindowsPaths (assuming I understand this correctly), but it does not seem to work when I deploy to GCP.
Edit: I have attempted to recreate the entire model on a Google Colab notebook assuming that my operating system was the issue, but I receive the exact same error even after doing this and replacing the model.pkl file. Does fastai not deal very well with os
or something?
app.py:
import imghdr
import os
from fastai.vision.all import *
import sys
from flask import Flask, render_template, request, redirect, url_for, abort, \
send_from_directory
from werkzeug.utils import secure_filename
import pathlib
app = Flask(__name__, static_url_path='',
static_folder='./static',
template_folder='./templates')
app.config['MAX_CONTENT_LENGTH'] = 1024 * 1024
app.config['UPLOAD_EXTENSIONS'] = ['.jpg', '.png', '.gif','.jpeg']
app.config['UPLOAD_PATH'] = '/tmp'
temp = pathlib.PosixPath
pathlib.PosixPath = pathlib.WindowsPath
try:
import googleclouddebugger
googleclouddebugger.enable(
breakpoint_enable_canary=True
)
except ImportError:
pass
def validate_image(stream):
header = stream.read(512) # 512 bytes should be enough for a header check
stream.seek(0) # reset stream pointer
format = imghdr.what(None, header)
if not format:
return None
return '.' + (format if format != 'jpeg' else 'jpg')
def deleteImages():
for f in os.listdir(app.config['UPLOAD_PATH']):
file_ext = os.path.splitext(f)[1:]
if file_ext in app.config['UPLOAD_EXTENSIONS']:
os.remove(os.path.join(app.config['UPLOAD_PATH'], f))
def predict(img_path):
temp = pathlib.WindowsPath
pathlib.WindowsPath = pathlib.PosixPath
learn = load_learner('./static/model1.pkl')
pathlib.WindowsPath = temp
pred_classes, pred_idx, probs = learn.predict(img_path)
return pred_classes, pred_idx, probs
@app.route('/')
def index():
if os.listdir(app.config['UPLOAD_PATH']):
deleteImages()
files = os.listdir(app.config['UPLOAD_PATH'])
return render_template('index.html', files=files)
@app.route('/', methods=['POST'])
def upload_files():
if os.listdir(app.config['UPLOAD_PATH']):
deleteImages()
uploaded_file = request.files['file']
filename = secure_filename(uploaded_file.filename)
if filename != '':
file_ext = os.path.splitext(filename)[1]
if file_ext not in app.config['UPLOAD_EXTENSIONS'] or \
file_ext != validate_image(uploaded_file.stream):
abort(400)
img_path = os.path.join(app.config['UPLOAD_PATH'], filename)
uploaded_file.save(os.path.join(app.config['UPLOAD_PATH'], filename))
pred_classes, pred_idx, probs = predict(img_path)
pred_classes = ', '.join([x.capitalize() for x in pred_classes])
probs = ', '.join([str(round(x, 4)) for x in probs[pred_idx].tolist()])
files = os.listdir(app.config['UPLOAD_PATH'])
return render_template('index.html', files=files, pred_class=pred_classes,
outputs=str(probs))
@app.route('/uploads/<filename>')
def upload(filename):
return send_from_directory(app.config['UPLOAD_PATH'], filename)
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8080, debug=True)
This is the error log I get from GCP:
Traceback (most recent call last):
File "/env/lib/python3.6/site-packages/flask/app.py", line 2073, in wsgi_app
response = self.full_dispatch_request()
File "/env/lib/python3.6/site-packages/flask/app.py", line 1518, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/env/lib/python3.6/site-packages/flask/app.py", line 1516, in full_dispatch_request
rv = self.dispatch_request()
File "/env/lib/python3.6/site-packages/flask/app.py", line 1502, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "/home/vmagent/app/app.py", line 61, in upload_files
pred_classes, pred_idx, probs = predict(img_path)
File "/home/vmagent/app/app.py", line 37, in predict
learn = load_learner('./static/model1.pkl')
File "/env/lib/python3.6/site-packages/fastai/learner.py", line 384, in load_learner
res = torch.load(fname, map_location='cpu' if cpu else None, pickle_module=pickle_module)
File "/env/lib/python3.6/site-packages/torch/serialization.py", line 594, in load
return _load(opened_zipfile, map_location, pickle_module, **pickle_load_args)
File "/env/lib/python3.6/site-packages/torch/serialization.py", line 853, in _load
result = unpickler.load()
File "/opt/python3.6/lib/python3.6/pathlib.py", line 1004, in __new__
% (cls.__name__,))
NotImplementedError: cannot instantiate 'WindowsPath' on your system