Dieser Artikel ist eine Zusammenfassung eines Versuchs, PyTorch unter AWS Lambda auszuführen. Es hat ein DeepLearning-Tag, berührt aber nicht das Lernen. Das Ziel ist es, einen Rückschluss auf Lambda zu ziehen. (Klicken Sie hier, um die EFS-Einstellungen anzuzeigen.](Https://qiita.com/myonoym/items/5d360ed11931474cb640))
Es ist ein dreizackiger Ständer.
Dieses Mal werde ich versuchen, es mit Lambda [EML-NET] auszuführen (https://www.sciencedirect.com/science/article/abs/pii/S0262885620300196). Weitere Informationen finden Sie unter Github-Projektseite, jedoch unter Saliency Map. ) Ist ein Modell zu generieren. SaliencyMap ist eine Heatmap, die die Position anzeigt, an der die Sichtlinie einer Person gerichtet ist.
Zitiert aus Artikel Abbildung 1
Ich habe EFS auf / mnt in Vorheriger Artikel gemountet, aber lassen Sie uns die Bibliothek, die ich aus Lambda importieren möchte, in EFS einfügen.
$ cd /mnt/lambda
$ sudo pip3 install -t . torch==1.6.0+cpu torchvision==0.7.0+cpu -f https://download.pytorch.org/whl/torch_stable.html
$ sudo pip3 install --upgrade -t . opencv-python==4.4.0.42 scipy==1.5.2
dadurch,
Ist jetzt unter / mnt / lambda
.
Klicken Sie auf "Funktion erstellen" -> "Von Grund auf neu erstellen" -> Geben Sie den Funktionsnamen ein -> Setzen Sie die Laufzeit auf "Python3.7" -> "Funktion erstellen"
VPC Hier in der Nähe Es wurde etwas geschrieben, aber um Lambda mit EFS zu verbinden, ist Lambda VPC. Muss hineingelegt werden. Die Standard-VPC sollte in Ordnung sein. In Bezug auf die Sicherheitsgruppe denke ich, dass es eine EC2-Einstellung gibt, die zum Vorbereiten der Bibliothek in EFS verwendet wird. Geben Sie diese an. Wenn ich auf Speichern klicke, wird folgende Fehlermeldung angezeigt: Ich scheine nicht genug Autorität zu haben. Laut hier
ec2:CreateNetworkInterface
ec2:DescribeNetworkInterfaces
ec2:DeleteNetworkInterface
Es scheint, dass Lambda die Erlaubnis von braucht. Es ist in der AWS-Verwaltungsrichtlinie AWSLambdaVPCAccessExecutionRole enthalten. Fügen Sie diese Richtlinie also der Lambda-Rolle hinzu. Dann sollten Sie in der Lage sein, die VPC einzurichten.
Verbinden Sie das vorbereitete EFS und Lambda. Klicken Sie in der Konsole unter "Dateisystem" auf "Dateisystem hinzufügen". Geben Sie das EFS-Dateisystem und den Zugriffspunkt an, setzen Sie den lokalen Mount-Pfad auf "/ mnt / lambda" und klicken Sie auf "Speichern".
Testen wir, ob Lambda die Bibliothek in EFS laden kann.
EFS ist auf / mnt / lambda
gemountet, also füge / mnt / lambda
zum Python-Pfad hinzu.
lambda_function.py
import json
import sys
sys.path.append("/mnt/lambda")
import torch
import torchvision
import PIL
import cv2
import numpy as np
def lambda_handler(event, context):
print(f"torch:{torch.__version__}")
print(f"torchvision:{torchvision.__version__}")
print(f"PIL:{PIL.__version__}")
print(f"cv2:{cv2.__version__}")
print(f"numpy:{np.__version__}")
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
Wenn Sie ein geeignetes Testereignis auf der Konsole erstellen und den Test ausführen, erhalten Sie das folgende Ergebnis. Sie können PyTorch richtig lesen.
START RequestId: 35329cd4-50f6-4eb7-8950-f27daf75462b Version: $LATEST
OpenBLAS WARNING - could not determine the L2 cache size on this system, assuming 256k
torch:1.6.0+cpu
torchvision:0.7.0+cpu
PIL:7.2.0
cv2:4.4.0
numpy:1.19.2
END RequestId: 35329cd4-50f6-4eb7-8950-f27daf75462b
REPORT RequestId: 35329cd4-50f6-4eb7-8950-f27daf75462b Duration: 29212.21 ms Billed Duration: 29300 ms Memory Size: 128 MB Max Memory Used: 129 MB
Nachdem wir fertig sind, verschieben wir das Modell. Der Speicherort des trainierten Modells ist auf EML-Github-Seite aufgeführt. Laden Sie es daher herunter. Fügen Sie gemäß der Lehre von README drei Dateien, res_imagenet.pth, res_places.pth, res_decoder.pth
, in das EFS / mnt / lambda / backbone
ein, das von scp auf EC2 gemountet wurde.
Basierend auf eval_combined.py werden wir es so ändern, dass es auf Lambda ausgeführt werden kann.
lambda_function.py
import sys
sys.path.append("/mnt/lambda")
import os
import torch
import torch.nn as nn
import torch.backends.cudnn as cudnn
import torchvision.transforms as transforms
from PIL import Image
import cv2
import numpy as np
import resnet
import decoder
#Ist die Umgebungsvariable hier nicht unnötig? Das fühle ich auch.
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
image_model_path = "/mnt/lambda/backbone/res_imagenet.pth"
place_model_path = "/mnt/lambda/backbone/res_places.pth"
decoder_model_path = "/mnt/lambda/backbone/res_decoder.pth"
size = (480, 640)
num_feat = 5
def normalize(x):
x -= x.min()
x /= x.max()
def post_process(pred):
pred = cv2.GaussianBlur(pred, (5,5), 10.0)
normalize(pred)
pred_uint = (pred * 255).astype(np.uint8)
return pred, pred_uint
def draw_heatmap(pred, img):
#Konvertieren Sie die Ausnahmekarte in die ursprüngliche Bildgröße.
resized_pred = np.asarray(Image.fromarray(pred).resize((img.size[0], img.size[1])), dtype=np.uint8)
resized_colormap = cv2.applyColorMap(resized_pred, cv2.COLORMAP_JET)
resized_colormap = cv2.cvtColor(resized_colormap, cv2.COLOR_BGR2RGB)
#Konvertieren Sie das Originalbild in numpy ndarray.
img_array = np.asarray(img)
#Mischen
alpha = 0.5
blended = cv2.addWeighted(img_array, alpha, resized_colormap, 1-alpha, 0)
return blended
def predict(image_model_path, place_model_path, decoder_model_path, pil_img):
img_model = resnet.resnet50(image_model_path).eval()
pla_model = resnet.resnet50(place_model_path).eval()
decoder_model = decoder.build_decoder(decoder_model_path, size, num_feat, num_feat).eval()
preprocess = transforms.Compose([
transforms.Resize(size),
transforms.ToTensor(),
])
processed = preprocess(pil_img).unsqueeze(0)
with torch.no_grad():
img_feat = img_model(processed, decode=True)
pla_feat = pla_model(processed, decode=True)
pred = decoder_model([img_feat, pla_feat])
pred_origin = pred.squeeze().detach().cpu().numpy()
pred, pred_uint = post_process(pred_origin)
heatmap = draw_heatmap(pred_uint, pil_img)
return heatmap
def lambda_handler(event, context):
#Leere Antwort
empty_response = {
"statusCode": 200,
"body": "{}"
}
pil_img = Image.open("/mnt/lambda/image/examples/115.jpg ").convert("RGB")
heatmap = predict(image_model_path, place_model_path, decoder_model_path, pil_img)
print(heatmap.shape)
return empty_response
Es ist ein bisschen lang, aber jetzt können Sie eine Saliency Map auf Lambda erstellen. Da die GPU auf Lambda nicht verwendet werden kann, wird die Beschreibung des cuda-bezogenen Teils gegenüber dem Originalcode geändert. Wenn du rennst
START RequestId: 6f9baccf-b758-4e9a-b43a-b92bdd9757ec Version: $LATEST
OpenBLAS WARNING - could not determine the L2 cache size on this system, assuming 256k
Model loaded /mnt/lambda/backbone/res_imagenet.pth
Model loaded /mnt/lambda/backbone/res_places.pth
Loaded decoder /mnt/lambda/backbone/res_decoder.pth
(511, 681, 3)
END RequestId: 6f9baccf-b758-4e9a-b43a-b92bdd9757ec
REPORT RequestId: 6f9baccf-b758-4e9a-b43a-b92bdd9757ec Duration: 20075.02 ms Billed Duration: 20100 ms Memory Size: 1024 MB Max Memory Used: 614 MB
Es scheint, dass es sicher ausgeführt werden kann. Ich wollte die Datei auf der EFS-Seite ausgeben, aber es war etwas nervig. Ändern wir sie also so, dass sie beim nächsten Aufruf von Slack an S3 ausgegeben werden kann.
Durch Verbinden von EFS mit Lambda können Sie jetzt Bibliotheken und Modelldateien laden. Ich denke, dies wird es ermöglichen, Modellinferenzen durchzuführen, ohne sich wie in der Vergangenheit um die Kapazität von Lambda sorgen zu müssen. Das nächste Mal werde ich diesen Lambda als Slack Call Edition von Slack anrufen und sehen.
Beim Schreiben dieses Artikels habe ich die Konfiguration zur Bestätigung erneut von Grund auf neu erstellt. Ich bedauere jedoch, dass das Schreiben Fortschritte gemacht hätte, wenn ich es mit AWS CDK oder ähnlichem gemacht hätte. Ich werde.
Recommended Posts