はじめに
Industry 4.0やスマートシティなど、動画をデータソースにAI解析を行って業務効率化などを行うユースケースが出ていますが、動画解析やAIをこれから始める人にとっては学習コストが高いかと思います。
本記事では、動画や時系列データをエッジで取り込み、分析や保存を行うアプリケーションを容易に実装できるIntel® Edge Insights for Industrial (EII)をインストールし、デフォルトで提供される不良品検知デモを構築します。
(Intel Edge Insights for Industrial だと長いので、以降、EIIと記載します)
OpenCV、OpenVINO、Edge Insights for IndustrialはIntel社の登録商標です。
EIIとは
EIIは、Intelの開発した動画解析アプリケーションのフレームワークで、Intelのホームページにて無料でダウンロードできます。画像解析はOpenCV、AIはOpenVINO™ベースのモデルを使っています。
また、各アプリケーションはDockerまたはKubernetesを用いてdeployされます。
ソースコードがGitHubで公開されてますので参考にして下さい。
deployするアプリケーション
今回は、EIIのvideo-streamingユースケースデモをdeployしてみたいと思います。
video-streamingユースケースでは、以下の5つのアプリケーションをdeployします。
| アプリ名 | 処理内容 |
|---|---|
| etcd | EIIのコアアプリケーションであり、EII上の各マイクロサービスのconfigを管理するKVSです。 |
| etcd-ui | etcd内のconfigをGUIで編集するためのetcd-keeperのWeb UIです。 |
| video-ingestion | 動画データをOpenCVやRTSPなどをインタフェースとして取り込み、jpgなどの画像取り込み、リサイズなどのフィルタリングを行なってキューへ格納します。キューはZeroMQが使われています。 |
| video-analytics | video-ingestionで取り込んだ画像データを、video-ingestionのキューから取り込み、推論などの処理を実行します。そして、その結果をキューへ格納します。 |
| web-visualizer | EIIのサンプリアプリケーションのデモ用のWeb UIです。video-analyticsのキューから画像を取り出し、UI表示します。 |
各コンテナ間の連携イメージを以下に示します。
開発環境
今回はAWSへインスタンスを1台deployしてEIIをインストールしました。
| 項目 | 値 |
|---|---|
| OS | Ubuntu18.04 |
| 台数 | 1 |
| 環境 | AWS |
| インスタンスタイプ | m5.xlarge |
| DISK | 100GB |
- 動画解析の場合はMEM 16GBが最低限必要で、時系列の取り込みと分析は2GBで十分の様です。
- EIIのインストールはDocker、docker-compose or Kubernetes(Helm)が使われますので、OSはDockerが動けばなんでも大丈夫です。ただ、gitに記載の通り、検証済みのUbuntu 18.04LTSが確実です。
- DISKは最低でも64GB必要です。
EIIのインストール
1. AWSへ開発用インスタンスをdeploy
今回は、Terraformを用いてAWSへUbuntuインスタンスを1台deployします。
任意のディレクトリにcompute.tfとnetwork.tfを設置します。
1-1. 作業ディレクトリの準備
$ mkdir work
$ cd work
$ tree
├── compute.tf
└── network.tf
1-2. インスタンス展開用のモジュール作成
# ====================
#
# Variables
#
# ====================
# 自身の環境に合わせて要修正!
variable "aws_access_key" {
default = "IAM_ACCESS_KEY"
}
# 自身の環境に合わせて要修正!
variable "aws_secret_key" {
default = "IAM_SECRET_KEY"
}
# Ubuntu
variable "ami" {
default = "ami-085e9421f80dbe728"
}
# 自身の環境に合わせて要修正!
variable "ssh_key_name" {
default = "KEY_NAME"
}
# 自身の環境に合わせて要修正!
variable "ssh_key_path" {
default = "KEY_PATH"
}
# 要件を満たすinstance typeを選択
variable "instance_type" {
default = "m5.xlarge"
}
# 今回はTokyoリージョンを選択
variable "aws_region" {
default = "ap-northeast-1"
}
# 任意のAvailability Zone
variable "aws_zone" {
default = "ap-northeast-1a"
}
provider "aws" {
access_key = "${var.aws_access_key}"
secret_key = "${var.aws_secret_key}"
region = "${var.aws_region}"
}
# ====================
#
# EC2
#
# ====================
resource "aws_instance" "instance" {
ami = "${var.ami}"
vpc_security_group_ids = [aws_security_group.public.id]
subnet_id = aws_subnet.public.id
key_name = aws_key_pair.instance.id
instance_type = "${var.instance_type}"
monitoring = false
root_block_device {
volume_type = "gp2"
volume_size = "100"
}
tags = {
Name = "dev-instance"
}
}
# ====================
#
# Elastic IP
#
# ====================
resource "aws_eip" "instance" {
instance = "${aws_instance.instance.id}"
vpc = true
}
# ====================
#
# Key Pair
#
# ====================
resource "aws_key_pair" "instance" {
key_name = var.ssh_key_name
public_key = file(var.ssh_key_path)
}
# ====================
#
# Output
#
# ====================
output "EIPはこちら" {
value = "${aws_eip.instance.public_ip}"
}
1-3. ネットワーク作成用のモジュール作成
network.tfの中身は以下です。
# ====================
#
# VPC
#
# ====================
resource "aws_vpc" "public" {
cidr_block = "10.0.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "public"
}
}
# ====================
#
# Subnet
#
# ====================
resource "aws_subnet" "public" {
cidr_block = "10.0.1.0/24"
availability_zone = "ap-northeast-1a"
vpc_id = aws_vpc.public.id
# trueにするとインスタンスにパブリックIPアドレスを自動的に割り当ててくれる
map_public_ip_on_launch = true
tags = {
Name = "public-sub"
}
}
# ====================
#
# Internet Gateway
#
# ====================
resource "aws_internet_gateway" "public" {
vpc_id = aws_vpc.public.id
tags = {
Name = "public-gw"
}
}
# ====================
#
# Route Table
#
# ====================
resource "aws_route_table" "public" {
vpc_id = aws_vpc.public.id
tags = {
Name = "public-rt"
}
}
resource "aws_route" "public" {
gateway_id = aws_internet_gateway.public.id
route_table_id = aws_route_table.public.id
destination_cidr_block = "0.0.0.0/0"
}
resource "aws_route_table_association" "public" {
subnet_id = aws_subnet.public.id
route_table_id = aws_route_table.public.id
}
# ====================
#
# Security Group
#
# ====================
resource "aws_security_group" "public" {
vpc_id = aws_vpc.public.id
name = "public-sg"
tags = {
Name = "public-sg"
}
}
# Inbound(ssh)
resource "aws_security_group_rule" "in_ssh" {
security_group_id = aws_security_group.public.id
type = "ingress"
cidr_blocks = ["0.0.0.0/0"]
from_port = 22
to_port = 22
protocol = "tcp"
}
# Inbound(ICMP)
resource "aws_security_group_rule" "in_icmp" {
security_group_id = aws_security_group.public.id
type = "ingress"
cidr_blocks = ["0.0.0.0/0"]
from_port = -1
to_port = -1
protocol = "icmp"
}
# Inbound(EII Web Visualizer)
resource "aws_security_group_rule" "in_webvisualizer" {
security_group_id = aws_security_group.public.id
type = "ingress"
cidr_blocks = ["0.0.0.0/0"]
from_port = 5000
to_port = 5001
protocol = "tcp"
}
# Inbound(EII etcd-ui)
resource "aws_security_group_rule" "in_etcd_ui" {
security_group_id = aws_security_group.public.id
type = "ingress"
cidr_blocks = ["0.0.0.0/0"]
from_port = 7070
to_port = 7071
protocol = "tcp"
}
# Outbound
resource "aws_security_group_rule" "out_all" {
security_group_id = aws_security_group.public.id
type = "egress"
cidr_blocks = ["0.0.0.0/0"]
from_port = 0
to_port = 0
protocol = "-1"
}
1-4. Terraform初期化
$ terraform init
1-5. dry-run
$ terraform plan
1-6. インスタンス作成
$ terraform apply
Enter a value: yes
Apply complete! Resources: 13 added, 0 changed, 0 destroyed.
Outputs:
EIPはこちら = "<作成したインスタンスのグローバルIPアドレス>"
2. EIIインストールに必要な環境の構築
2-1. 作成したインスタンスへアクセス
$ ssh -i <KEY> ubuntu@<作成したインスタンスのグローバルIPアドレス>
2-2. アップデート
$ sudo apt-get -y update
2-3. Docker-CEインストール
$ sudo apt-get -y install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
$ sudo apt-get -y update
$ sudo apt-get -y install docker-ce
$ sudo systemctl start docker
$ sudo systemctl enable docker
参考URL
2-4. Docker-composeインストール
$ sudo apt-get -y install jq
$ sudo curl -L https://github.com/docker/compose/releases/download/$(curl https://api.github.com/repos/docker/compose/releases/latest | jq .name -r)/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
3. EIIソースコードの入手
詳細は以下の手順を参照して下さい。
3-1. EIIインストールで必要となるPython3のパッケージをインストール
$ sudo apt-get -y install python3-pip
$ sudo pip3 install jsonmerge
$ sudo pip3 install ruamel.yaml
3-2. repoツールをダウンロード
$ sudo curl https://storage.googleapis.com/git-repo-downloads/repo > repo
$ sudo mv repo /bin/repo
$ sudo chmod a+x /bin/repo
3-3. 作業ディレクトリを作成
$ mkdir -p <work-dir>
$ cd <work-dir>
3-4. gitのユーザ名とメールアドレスを設定
$ sudo git config --global user.name "USERNAME"
$ sudo git config --global user.email "MAIL_ADDRESS"
3-5. python3コマンドのシンボリックリンクを作成
ダウンロードしたrepoコマンドはpython3コマンドでなくpythonコマンドを実行する実装になっています。
そのため、python3コマンドのシンボリックリンク pythonを作成しておきます。
$ sudo ln -s /usr/bin/python3 /usr/bin/python
3-6. EIIのソースコードをダウンロード
$ sudo repo init -u "https://github.com/open-edge-insights/eii-manifests.git"
...
Enable color display in this user account (y/N)? y
$ sudo repo sync
4. EIIインストールのためのconfig作成
詳細は以下の手順を参照して下さい。
4-1. 環境変数を修正
<work-dir>/IEdgeInsights/build/配下にある.envの下記の箇所を修正します。
今回はデモのため、DEV_MODE=trueとして構築します。
DEV_MODE=falseは、各マイクロサービスがEIIのetcdへ接続する際に、暗号化して接続するモードになります。
DEV_MODE=trueの場合は、特に暗号化されず接続します。
その他、必要に応じて環境変数を設定して下さい。
同一環境にKubernetesがインストールされている場合、etcdのポート番号がバッティングしますので、
必ず下記の71-72行目を修正し、EIIのetcdのポート番号を変更して下さい。
$ cd IEdgeInsights/build/
$ sudo vi .env
...
26 DEV_MODE=true #DEV_MODEでdeployする
...
# 初回インストール時は設定しないでください。(イメージのpull先として指定されます)
40 DOCKER_REGISTRY=
41 DOCKER_USERNAME=
42 DOCKER_PASSWORD=
...
71 ETCD_CLIENT_PORT=2379
72 ETCD_PEER_PORT=2380
...
4-2. ビルド用docker-compose.yaml生成
builder.pyを実行し、docker-composeのファイルを出力します。
また、今回はvideo-streamingユースケースデモをdeployしますので、-fに対象のyamlを指定します。
$ pwd
<work-dir>/IEdgeInsights/build/
$ sudo python builder.py -f ./usecases/video-streaming.yml
builder.pyを実行すると、docker-compose.yml docker-compose-build.yml docker-compose-push.yml が生成されます。それぞれの用途は以下の通りです。
| 項目 | 値 |
|---|---|
| docker-compose.yml | コンテナのdeploy |
| docker-compose-build.yml | コンテナイメージのbuid |
| docker-compose-push.yml | コンテナイメージのRegistryへのpush |
また、以下も同様に作成されます。
| 作成されるもの | 内容 | 作成場所 |
|---|---|---|
| eii-config.json | EII上へdeployしたマイクロサービスの設定 | IEdgeInsights/build/provision/config |
| values.yaml | Helmのvalues.yaml | IEdgeInsights/build/helm-eii/eii-provision |
4-3. etcdとetcd-provisionを起動
$ pwd
<work-dir>/IEdgeInsights/build
$ cd provision && sudo -E ./provision.sh ../docker-compose.yml
EIIはetcdで各マイクロサービスのconfigを一元化します。
etcd-provisionはeii_config.jsonの内容をetcdへ登録するコンテナです。
4-4. イメージ作成
$ pwd
<work-dir>/IEdgeInsights/build
$ sudo -E docker-compose -f docker-compose-build.yml build
1-2時間くらいかかりますので気長に待ちます。
4-5. コンテナdeploy
$ sudo docker-compose up -d
[+] Running 8/8
⠿ Volume "edgeinsightssoftware_vol_eii_socket" Created 0.0s
⠿ Volume "edgeinsightssoftware_vol_temp_webv" Created 0.0s
⠿ Volume "edgeinsightssoftware_vol_etcd_keeper" Created 0.1s
⠿ Container ia_etcd_ui Started 3.6s
⠿ Container ia_video_analytics Started 2.4s
⠿ Container ia_visualizer Started 2.5s
⠿ Container ia_web_visualizer Started 1.6s
⠿ Container ia_video_ingestion Started
$ sudo docker-compose ps
WARN[0000] network eii: network.external.name is deprecated in favor of network.name
NAME COMMAND SERVICE STATUS PORTS
ia_etcd "./start_etcd.sh" ia_etcd running (healthy) 0.0.0.0:2379->2379/tcp, :::2379->2379/tcp
ia_etcd_provision "python3 etcd_provis…" ia_etcd_provision exited (0)
ia_etcd_ui "python3 start_etcdk…" ia_etcd_ui running (starting) 0.0.0.0:7070-7071->7070-7071/tcp, :::7070-7071->7070-7071/tcp
ia_video_analytics "./VideoAnalytics/va…" ia_video_analytics running (starting) 0.0.0.0:65013->65013/tcp, :::65013->65013/tcp
ia_video_ingestion "./VideoIngestion/vi…" ia_video_ingestion running (starting) 0.0.0.0:64013->64013/tcp, :::64013->64013/tcp
ia_visualizer "./visualizer_start.…" ia_visualizer restarting
ia_web_visualizer "./web_visualizer_st…" ia_web_visualizer running (starting) 0.0.0.0:5000-5001->5000-5001/tcp, :::5000-5001->5000-5001/tcp
EIIでは、まずia_etcd_provisionがeii_config.jsonを読み込み、etcdへ格納します。
ia_etcd_provisionにて以下の様なログが出力されていれば、正常にプロビできてます。
$ sudo docker-compose logs ia_etcd_provision
WARN[0000] network eii: network.external.name is deprecated in favor of network.name
ia_etcd_provision | =======Adding key/values to etcd========
ia_etcd_provision | Added /EtcdUI/config key successfully
ia_etcd_provision | Added /EtcdUI/interfaces key successfully
ia_etcd_provision | Added /GlobalEnv/ key successfully
ia_etcd_provision | Added /VideoAnalytics/config key successfully
ia_etcd_provision | Added /VideoAnalytics/interfaces key successfully
ia_etcd_provision | Added /VideoIngestion/config key successfully
ia_etcd_provision | Added /VideoIngestion/interfaces key successfully
ia_etcd_provision | Added /Visualizer/config key successfully
ia_etcd_provision | Added /Visualizer/interfaces key successfully
ia_etcd_provision | Added /WebVisualizer/config key successfully
ia_etcd_provision | Added /WebVisualizer/interfaces key successfully
ia_etcd_provision | =======Reading key/values from etcd========
ia_video_ingestion、ia_video_analytics、ia_etcd_ui、ia_web_visualizer、ia_visualizerは、etcdへ接続し、eii_config.jsonに設定されたパラメータを読み込み、処理を行います。
尚、ia_visualizerはXWindowへ接続している状態でないと起動しません。
4-6. デモアプリケーションの表示
ia_video-ingestion、ia_video-analytics、ia_web_visualizerのSATUSがrunningになったら、ブラウザを開き5001番ポートへ接続します。
http://<作成したインスタンスのグローバルIPアドレス>:5001/
すると、以下の様なログイン画面が表示されます。
ユーザ名とパスワードはeii_config.jsonの/WebVisualizer/config/usernameと/WebVisualizer/config/passwordに記載されています。
$ pwd
<work-dir>/IEdgeInsights/build
$ cd provision/config/
$ cat eii_config.json | jq '."/WebVisualizer/config" | .username, .password'
ログインすると、下記の画面が表示されます。
ia_video_ingestionが<work>/IEdgeInsights/VideoIngestion/test_videosに配置されたpcb_d2000.aviを読み込み、jpgファイルへ変換して、ia_video_analyticsが不良箇所を検知するデモになってます。
ブラウザはGoogle Chrome推奨です。
4-7. eii_config.jsonの編集
eii_config.jsonにはdeployした各マイクロサービスの設定パラメータが記載されています。
パラメータを修正したい場合に、改めてコンテナイメージをビルドするのも一つの手段ですが、etcd-keeperのWeb UIを使用して変更することも可能です。Web UIはブラウザを開いて7071番ポートへアクセスします。
http://<作成したインスタンスのグローバルIPアドレス>:7071/
表示された画面上でetcdkeeper/をクリックすると以下の画面が表示されます。
この画面上でeii_config.jsonを修正して[save]ボタンを押した後、対象のコンテナを再作成すれば設定が反映されます。
(今回の手順ではetcdのdataを永続化していませんので、etcdコンテナは再作成しないでください)



