LoginSignup
3
1

More than 3 years have passed since last update.

pythonを利用したS3とEC2内一時ディレクトリのファイルやり取り

Last updated at Posted at 2020-07-22

はじめに

オンプレ環境のGPUを持っていないので、私はAWSでGPUインスタンスを立ててディープラーニングを行っている。
学習データを利用する際、EC2内に一時ディレクトリを作成して、そこにS3から学習データをダウンロードして使うことで、以下のような利点が得られるんじゃないかと思ったので、紹介する。

EC2インスタンス上にデータを入れっぱなしにしておくよりも、プログラムの実行が終わった際にEC2インスタンスからデータが消去される、かつS3に出力結果が上がるため、セキュリティの強化、出力結果紛失の危険性低減、EBS(ストレージ)の節約になる。

この記事では、EC2インスタンス内に一時ディレクトリを作成し、そこにS3からファイルをダウンロードする。
そして、一時ディレクトリからS3へのアップロードするまでを目指す。

必要作業

  • EC2にIAMロールの設定
  • pythonモジュールのインストール(python3を利用)
  • コードの記述

IAMロールの設定

ロールの作成

①AWSマネジメントコンソールからIAMのページに移動
②左のメニュー一覧からロールを選択
③ロールを作成を選択

_2020-07-17_17.28.55.png

④ユースケースはEC2を選択
⑤次のステップへ

_2020-07-17_17.35.44.png

⑥検索窓でS3と入力し検索
⑦AmazonS3FullAccessにチェックマークを入れる
⑧次のステップへ

_2020-07-17_17.42.51.png

⑨タグは設定してもしなくてもどちらでも良いが、複数人でAWSを利用している場合は、管理のしやすさのため、Userのみ設定しておくと良い
⑩次のステップへ

_2020-07-17_17.46.21.png

⑪任意のロール名をつける(ロール名から何ができるロールなのかわかるようにしておくと楽)
⑫ロールの作成

_2020-07-17_17.50.16.png

EC2インスタンスへのIAMロールの割当

EC2インスタンスを作成する際に先程作成したIAMロールを割り当てる

※インスタンス作成時にしかロールの割当できないかも?作成後にロールが割り当てられるかは要検証

_2020-07-17_18.04.46.png

pythonモジュールのインストール

必要モジュール

AWSモジュール
- boto3
一時ディレクトリモジュール
- tempfile(python標準モジュールのためインストール不要)

インストールコマンド

pip install boto3

コードの記述

以下のコードをノートブックファイルや.pyファイルにコピペすればダウンロード及びアップロードの完了

ダウンロード元やアップロード先の設定

import boto3
import tempfile

#ダウンロード元バケット名
bucket_name = 'hogehoge'
#アップロード先バケット名今回はダウンロード先と同じ
out_bucket_name = bucket_name

#バケットにある動画ファイル名
file_name = 'input.mp4'

#アップロード先のフォルダ名
#下記の例だとS3にresultフォルダが作成されそこに出力される
out_folder_name = 'result'

一時ディレクトリの作成及びS3からのダウンロード

#一時保存用ディレクトリの作成
tmpdir = tempfile.TemporaryDirectory()
tmp = tmpdir.name + '/'

#一時的な入力ファイル名適当な名前で固定
#固定された名前で一時フォルダにダウンロードされる
tmp_input = tmp + 'tmp.mp4'

#S3からファイルをダウンロード
s3_client = boto3.client('s3')
s3 = boto3.resource('s3')
bucket = s3.Bucket(bucket_name)
bucket.download_file(file_name, tmp_input)

ダウンロードされたファイルの使用例

以下の例はopencvで読み込みをし、何も処理せず一時ディレクトリに別名保存している

(一時ディレクトリにtmp.mp4とoutput.mp4がある状態)

import cv2

#一時ディレクトリに保存するビデオ名の設定
output_video =tmp + 'output.mp4'

#動画ファイルを読み込む
video = cv2.VideoCapture(tmp_input)

# 幅と高さを取得
width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
size = (width, height)

#総フレーム数を取得
frame_count = int(video.get(cv2.CAP_PROP_FRAME_COUNT))

#フレームレート(1フレームの時間単位はミリ秒)の取得
frame_rate = int(video.get(cv2.CAP_PROP_FPS))

# 保存用
fmt = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
writer = cv2.VideoWriter(output_video, fmt, frame_rate, size)

for i in range(frame_count):
    ret, frame = video.read()
    ### ここに加工処理などを記述する ###
    writer.write(frame)

writer.release()
video.release()
cv2.destroyAllWindows()#ビデオの読み込み

S3へのアップロード

以下の例は先に設定したS3アップロード先にoutput_video.mp4という名前で上で作成したビデオがアップロードされている。

s3.Bucket(out_bucket_name).upload_file(output_video,out_folder_name+'/'+ 'output_video.mp4')

一時ディレクトリの削除

tmpdir.cleanup()

まとめ

それぞれの技術についてもっと細かく解説しているサイトはたくさんあると思うが、それをどうやってうまく組み合わせるのかが意外と難しいと思いこの記事を作成した。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1