Taste of Tech Topics

Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

RustのCI環境でクロスコンパイルを行う

こんにちは
@maron8676です

今回は、RustプロジェクトでのCI環境構築について紹介します。
最近、自然言語処理のエンジン開発をRustで行っており、その中で実際に試した内容となっています。

Rust

Rustは安全性を担保しつつ、高速なアプリケーションを開発するのに便利なプログラミング言語です。
例えば、以下のような特徴があります。

  1. 同じ値の種類でも、不変な変数と可変な変数では別の型になっており、意図しない変更をコンパイルエラーとして検知できる
  2. ポインタの有効範囲がプログラムで示されるため、無効なアドレスへの参照をコンパイルエラーとして検知できる

公式ページには、以下のように書かれています。

RustはMozillaとコミュニティによって作成された、オープンソースプログラミング言語です。
開発者が最新のマルチコアプロセッサの強力な機能を最大限に活用して、高速で安全なアプリケーションを作成できるように設計されたおり、セグメンテーション違反を防ぎ、スレッドの安全性を保証します。

バイナリの自動作成

Rustで書かれたプログラムを実行するには、実行環境に合わせてコンパイルを行い、実行可能バイナリを作成する必要があります。
Rustのコンパイルは他言語と比較して遅めなので、pushなどをトリガーにしてコンパイルを行います。
実行可能バイナリを作成できるとすぐにバイナリを利用できて便利です。
ここでは、GitLab CI/CDを使ってWindows用バイナリを自動作成する方法を紹介します。

通常のビルド、実行手順

CI環境のビルド方法を見る前に、通常ローカルPCで行うビルド、実行手順について見ていきましょう。
Rustには、cargoというコマンドが含まれています。
このコマンドでビルド、パッケージ管理、ドキュメント生成といった、開発に必要な作業を簡単に行うことができます。

では、ビルド手順を見ていきます。コマンドプロンプトでプロジェクトディレクトリまで移動して、

cargo build

を実行することで、プロジェクトをビルドできます。
--release オプションを付けると、プロダクションビルドできます。
ビルドが成功した場合は、

cargo run

でプログラムを実行できます。
ビルドが成功した時点で、プロジェクトディレクトリのtarget配下にexeファイルが作成されています。
そのため、その場所まで移動したり、ファイルを移動したりして、直接実行も可能です。

CI環境でのビルド手順(GitLab CI/CD パイプライン設定)

全体としては以下のようになります。
こちらを実行することで、GitLabCIのPipelinesからビルド結果のファイルをダウンロードできるようになります。
f:id:acro-engineer:20200509104404j:plain

image: ubuntu:18.04  # 1. image選択

variables:
  TOOLCHAIN: "1.41.1"
  TARGET: "x86_64-pc-windows-gnu"

build:
  script:
    - apt update && apt install -y --no-install-recommends ca-certificates curl gcc g++ g++-mingw-w64-x86-64 # 2. 必要なパッケージのインストール
    - curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain $TOOLCHAIN -t $TARGET # 3. Rustのインストール
    - export CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER=x86_64-w64-mingw32-gcc CC_x86_64_pc_windows_gnu=x86_64-w64-mingw32-gcc-posix CXX_x86_64_pc_windows_gnu=x86_64-w64-mingw32-g++-posix # 4. 環境変数の設定
    - cargo build --target $TARGET # 5. ビルド
  artifacts:
    paths:
      - target/x86_64-pc-windows-gnu/release/my_project.exe # 6. 成果物の保存

各要素の説明

  1. image選択
    実はRust公式のdockerイメージ(debianベース)があるのですが、
    debianベースで試行錯誤してもwindowsコンパイルを成功させることができなかったため、
    cross*1を参考にして、ubuntuベースで作ることにしました。
     
  2. 必要なパッケージのインストール
    scriptの1行目では、Rustのインストールに必要なca-certificatesとcurl 、ビルド時に必要なgcc関連をインストールしています。
     
  3. Rustのインストール
    scriptの2行目では、Rustをインストールしています。
    インストール時に--default-toolchainオプションでRustバージョンを、
    -tオプションでビルドターゲットに加える内容を指定できます。
     
  4. 環境変数の設定
    scriptの3行目では、ビルド設定に関わる環境変数を設定しています。
     
  5. ビルド
    scriptの4行目でビルドを行っています。
    cargo buildコマンドに--targetオプションを付けることで、ビルドターゲットを指定できます。
    今回はWindows64bitをターゲットにしています。
     
  6. 成果物の保存
    ビルド結果は所定の場所にできるため、成果物として登録しています。
    ファイル名がmy_project.exeとなっていますが、これはCargo.tomlのnameに書かれた文字列が使われます。

まとめ

本記事では、RustプロジェクトをクロスコンパイルするCI設定について紹介しました。
ビルドの遅さをカバーして、実行時だけでなく開発や動作確認のスピードも上げていきたいですね。

Acroquest Technologyでは、キャリア採用を行っています。


  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
モノリシックなアプリケーションをマイクロサービス化したいエンジニア募集! - Acroquest Technology株式会社のWebエンジニアの求人 - Wantedlywww.wantedly.com

*1:crossは実行環境でdockerが使えることを前提としているので、
CIジョブのランナーとしてdockerコンテナを使用する場合は、docker in dockerとなってしまいビルドできません。

GiNZAの固有表現抽出とElasticsearchを使って自動でタグ検索

こんにちは。@Ssk1029Takashiです。
最近は家でもどうにかラーメンを食べられないかと試行錯誤しています。

タグ検索とは、キーワード検索とは違い、検索する前からユーザーが選択肢からキーワードをセレクトボックスなどで選んで、検索できる検索方法です。
通常のキーワード検索と違って、ユーザーが0からキーワードを考える必要がないため、効率的に情報を絞り込めます。
もしくは、キーワード検索と併用して使用することも可能です。

ただ、コンテンツごとにタグを設定するのはとても手間がかかります。
コンテンツ作成者も必ずしもタグを設定してくれるとは限りません。
このような時に、自動でタグ付けをしてくれる仕組みがあると楽にタグ検索を実現できます。

ただ、単純な形態素解析で名詞をタグとすると、ゴミが多くなってしまいます。
そこで、今回は、日本語処理ライブラリであるGiNZAの固有表現抽出機能とElasticsearchを使って、簡易的にタグ検索を実現してみます。

今回のゴール

タグ検索というと、以下の画面のようにタグをチェックボックスで選択して、選択したタグによって検索結果が変わる画面が一般的です。
f:id:acro-engineer:20200426155821p:plain

今回目指すのは上記の検索のデータ投入・検索クエリを作成していきます。

今回書かないこと

本記事は以下のことは対象外としています。
1. 検索画面の実装
2. Elasticsearchの基本的なクエリの使い方

GiNZAとは

GiNZAについては、過去にブログで紹介しているので、詳細はそちらを参照してください。
acro-engineer.hatenablog.com

今回はこのGiNZAの固有表現抽出をタグ付けに使用していきます。

固有表現抽出とは

固有表現抽出とは、自然言語処理技術のうちの一つで、文章中から人名・組織名・地名などの固有名詞や、「100%」などの数値表現を抽出する技術です。
一般的には、以下の8つのクラスが固有表現のクラスとして抽出されます。
ART 固有物名、LOC(地名)、ORG(組織)、PSN(人名)、DAT(日付)TIM(時間)、MNY(金額)、PNT(割合)

どういうときに使われるかというと、例えば、未知語を辞書登録するために固有名詞を抽出したり、人名・企業名を抽出してプライバシー保護に使用したりなどが考えられます。

GiNZAの場合、より細かいクラスを定義しています。
拡張固有表現階層 定義
GiNZAはGSK2014-A (2019) BCCWJ版という、上記の固有表現クラスを定義したコーパスで学習されたモデルをもとに固有表現抽出を行います。

非常に細かく固有表現を分類しているので、より詳細な分析ができるようになっています。

今回は、文章中の固有表現はその文章の中心的な話題を示すことが多いのではないか仮定して、タグ検索に応用してみます。

どうやって解決するか

以下に概略図を書きました。
f:id:acro-engineer:20200425084125p:plain

つまり、本文とは別にGiNZAで固有表現として抽出したキーワードをタグとしてElasticsearchに投入します。
検索時はタグとして投入したキーワードの一覧を取得します。

GiNZAでの固有表現抽出

まず、GiNZAで固有表現抽出を試してみましょう。

実際に動かすコードは以下のようになります。

import spacy

nlp = spacy.load('ja_ginza')
doc = nlp("Acroquestは新横浜にある会社です。")

for ent in doc.ents:
    print(ent.text, ent.start_char, ent.end_char, ent.label_)

出力結果

Acroquest 0 9 Company
新横浜 10 13 City

ちゃんと「Acroquest」を会社、「新横浜」を地名と認識しています。

また、Spacyには固有表現抽出された結果をより分かりやすく可視化する機能もあります。

from spacy import displacy

displacy.render(doc, style="ent", jupyter=True)

結果
f:id:acro-engineer:20200419171932p:plain

このように、文章のどの単語が固有表現として抽出されたのかを一目で確認できます。

検索に応用する

それではElasticsearchと固有表現抽出を使ったタグ検索を実現していきます。

検索データを作る

コードにすると以下のようになります。

nlp = spacy.load('ja_ginza')
es_client = Elasticsearch()

for title, sentence in zip(titles, sentences):
  doc = nlp(sentence)
  tags = [ent.text.lower() for ent in doc.ents]
  tags = list(set(tags)) #重複するタグを削除
  document = {
      "title": title,
      "sentence": sentence,
      "tag": tags
  }
  es_client.index(index="content", doc_type="_doc", body=document)

各フィールドの値は以下のようにします。

フィールド 説明
title 記事のタイトル(画面表示用に投入)
sentence 記事本文
tag 記事から固有表現抽出で作成したタグ

試しに、このブログのここ最近の冒頭文とタイトルを入れてみました。
Elasticsearchに投入後は、以下のようにデータが登録されます。
(抜粋)

{
    "title": "LINE BotとAmazon Rekognitionでワーク&ライフハック",
    "sentence": """
こんにちは、DevOpsエンジニアの横山です。
今回は、LINE BotAWSの画像分析サービスを使って社員のワーク&ライフハックを行った内容を紹介したいと思います。
             """,
          "tag": [
        "line bot",
        "社員",
        "aws",
        "横山",
        "devopsエンジニア"
    ]
},
{
    "title" : "ANGEL Dojo最終発表で「アライアンス賞」を受賞しました!",
    "sentence" : """
こんにちは!
2年目エンジニアの古賀です。
先日ブログで紹介したANGEL Dojoですが、 2020年3月6日、最終発表があり、AWSの審査員の方々が選ぶ「アライアンス賞」を受賞しました!
上位3チームに選ばれると貰える賞の1つで、 今回がんばってきたことが1つの形になって、とても嬉しいです。
アライアンス賞の詳細は後ほど^^
※ANGEL Dojo とは、AWS様主催の疑似プロジェクトを通して、 クラウド開発力とAmazonの文化を学び、ビジネスで日本を元気にしよう! という企画です。
       """,
    "tag" : [
      "2020年3月6日",
      "上位3チーム",
      "angel dojo",
      "aws",
      "2年",
      "古賀",
      "日本",
      "アライアンス賞",
      "amazon",
      "審査員",
      "1つ",
      "目エンジニア"
    ]
  }
},

入ったタグをKibanaのタグクラウドで見てみると以下のようになります。
f:id:acro-engineer:20200425154433p:plain
最近記事が多かったANGEL DojoやAutoGluonなどの単語が拾えていますね。

数値表現や日付が混じってしまっていますが、GiNZAは固有表現で識別したクラスも取得できるので、数値や日付はフィルタするようにすればより精度が高く抽出できます。

検索する

データが入れば、次は検索してみましょう。
タグ検索には以下の2ステップが必要です。
1. タグの一覧取得
2. 選択したタグでの検索

1のタグ一覧の取得はtagフィールドに対して、Terms Aggregationを実行することで取得できます。

GET content/_search
{
  "size": 0,
  "aggs": {
    "terms": {
      "terms": {
        "field": "tag",
        "size": 10
      }
    }
  }
}

上のクエリで、tagをリストを出現数順に取得することができます。

2の選択したタグでの検索は、1で取得したタグから選択した値をtagフィールドにTerms Queryで検索することで取得できます。

GET content/_search
{
  "size": 0,
  "aggs": {
    "terms": {
      "terms": {
        "field": "tag",
        "size": 10
      }
    }
  }
}

以上で、GiNZAを使ったタグ検索は実現できます。

画面にすると以下のようになります。
f:id:acro-engineer:20200426155821p:plain

0からキーワードを考えるよりも、なんとなくでも文書の内容がわかったほうが探しやすいですね。

まとめ

GiNZAの固有表現抽出とElasticsearchを使って自動でタグ検索を実現してみました。
改善点としては、数詞や日付が入ってしまっているので、抽出されたタグから固有表現のクラスでフィルタリングするとより精度の高いタグ検索が可能になります。
GiNZAは3.0から固有表現のクラスがより細かくなっているため、扱いやすくなっています。

それでは、皆さんもよいNLPライフを。

Acroquest Technologyでは、キャリア採用を行っています。


  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
Kaggle Masterと働きたい尖ったエンジニアWanted! - Acroquest Technology株式会社のデータサイエンティストの求人 - Wantedlywww.wantedly.com

Elastic{ON} Americas East 最速レポート!

f:id:acro-engineer:20200424012245p:plain:w600
こんにちは、Elastic Certified Engineerの@shin0higuchiです😊

日本時間4/23(木)22:00から、Elastic{ON} Americas Eastが、Webinar形式で開催されました。
例年、Elatic{ON} Tourという形で開催されていましたが、今年はCOVID-19の影響でオンライン開催に変更されています。
Elastic COVID-19 update | Elastic Blog を読むと経緯がわかります。)

COVID-19は早く収束してほしいですが、海外のイベントに自宅から参加できるのは嬉しいですね。
今回は、若手数名で参加したので、オムニバス形式で内容のまとめ・感想を書いて行きたいと思います!
※スクリーンキャプチャを利用していますが、ブログでの利用許可を主催者側に得ています。

Keynote

Elastic Certified Engineerのノムラです。
Keynoteは主にElastic社の3つのソリューションについての紹介の話でした。
f:id:acro-engineer:20200424012726p:plain:w400
シャイの眼鏡姿が新鮮ですね(笑)

Elastic社の3つのソリューションについての紹介

3つのソリューションとは

  • Search
  • Observability
  • Security

のことです。
この3つのソリューションに紐づくサービスについて、デモも交えながらの紹介でした。

各サービスの中でも個人的にはSearchのサービスの1つであるWorkplace Searchが印象的でした。
www.elastic.co
エンタープライズサーチにおいて、かなり強力なソリューションになりそうだと感じました。
GUIから簡単にリソースを連携/登録できるのが利用する際に便利そうです。

また、GUIマーケティング、開発、ファイナンスのようなグループを作成することができ、各グループにユーザを登録できます。
そのグループ毎に検索可能なリソースを割り当てることで「他グループには見せたくない」情報やドキュメントを管理できるのも魅力的だと感じました。

Combining Logs, Metrics, and Traces for Unified Observability

f:id:acro-engineer:20200424024957p:plain:w400
4年目エンジニアの緑川です。
このセッションでは、Logs, Metric, APM, Uptimeなど、複数のデータを1つのダッシュボードに統合し可視化していました。
Elastic Common Schemaにより、ソースが異なるデータもフォーマットが統一されるため、
分析が簡単に出来るようになっているので便利ですね。

Search for All with Elastic Workplace Search

f:id:acro-engineer:20200424023531p:plain:w400
Workplace searchは、Google DriveDropboxSharepointなどの異なるデータソースに保存されているデータを横断して検索可能です。
普段自分も、SharepointやOneDriveなど、複数のサービスを利用していますが、
自分が欲しい情報がどこにあるのかを探すのに時間がかかるため、非効率だと感じていました。
横断的に検索して見つけられる、かつ、UIから用意されたコネクタを設定するだけなので、お手軽で便利そうです。

Bandwidth: Use Cases for Elastic Cloud on Kubernetes

Bandwidth社における、Elastic Cloud on Kubernetes(ECK)の事例紹介。
f:id:acro-engineer:20200424013249p:plain:w400

Bandwidth社は、いわゆるCPaaS(communications platform as a service)の企業です。
www.bandwidth.com
クラスタの規模が大きいことや、PaaSという特性上、複数クラスタを運用するコストが課題となっていたようです。

Openshift/k8sの導入、Elastic Cloudの利用開始などの経緯について紹介していました。Ansibleによって複雑なデプロイメントを管理していたのをECKにしたことで運用コストが大幅に下がったということでした。
(学習・導入コストは大きかったが、それを大きく上回る益があったそうです)

Elastic Security: Enterprise Protection Built on the Elastic Stack

f:id:acro-engineer:20200424013508p:plain:w400
Elastic Stackが提供するセキュリティ機能についてのセッション。
分析者のスキルによらず、統一的なセキュリティ分析プラットフォームを提供できることだと思います。
セッションの中では次の3点を挙げていました。

  • eliminate blind spots
  • stop threats at scale
  • arm every analyst

デモの印象として、ひとたびElasticsearchにログを集約する仕組みさえ整えてしまえば、分析者のスキルがなくとも脅威を検出できそうだと感じました。 ちょっと前まで、ElasticsearchのMLでセキュリティ脅威を検出するために、データ加工や検出するためのロジックに頭を悩ませていただけに、感動も一入です。

最近Elasticが特に力を入れている部分だと思うので、今後にさらに期待したいですね😊

Elastic Stack Roadmap Deep Dive

再びノムラです。
本セクションではこれまでのロードマップの中から

  • Data Management
  • Data Analysis
  • Actions & Alerting

についてプレゼンとデモがありました。
その中でも特に印象的だったData Managementについて記載します。

Data Management

昨年新しく追加されたFrozen Indexの機能を踏まえたインデックスライフサイクルとデータストレージの運用についての話でした。
インデックスのライフサイクルに合わせて、

[↑検索頻度高↑]

  • Hot
  • Warn
  • Cold
  • Frozen

[↓検索頻度低↓]

と状態を変えていくことでヒープ(メモリ)とディスクをより効率的に利用することができます。

プレゼンではFrozen Idnexの内部的な仕組みについて、解説がありました。
詳細は割愛しますが、検索を高速化するために内部的に保持しているデータをFrozenでは保持しないようにすることでメモリの使用量を節約しているそうです。

上手く活用して大規模データでもコストを抑えられるようにしたいですね。

Elasticsearch on Azure

最後のセッションもノムラがお届けします。
このセッションでは、去年の12月にGAとなったAzureでのElasticsearch Serviceの紹介でした。以下のブログにも詳しく書かれています。
www.elastic.co

セッションの中では、今後のロードマップが発表され、

  • Azure Marketplaceの支払いと統合する
  • Elasticsearch ServiceでAzure Private Linkを利用可能とする

等によりAzureの他サービスとの統合/連携が簡易になっていくようです。
当社ではAzure上でElasticStackを利用するシーンもあるため、はやく実現して欲しいですね。

最後に

全体を通して、「Elastic Stackだけで全部できる」という点が強調されていたように思います。あらゆるデータを集約し、様々なユースケースにシームレスに対応できる。 改めてElastic Stackのパワーを感じました。

個人的にはWorkplace SearchのGAが近いことや、Endpoint Securityが今後どのようにStackに統合されていくのかは要注目だと感じました。


それでは、今回のレポートはこのあたりで。
お読みいただきありがとうございました😊


Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

世界初のElastic認定エンジニアと一緒に働きたい人Wanted! - Acroquest Technology株式会社のデータサイエンティストの求人 - Wantedlywww.wantedly.com

LINE BotとAmazon Rekognitionでワーク&ライフハック

こんにちは、DevOpsエンジニアの横山です。

今回は、LINE BotAWSの画像分析サービスを使って社員のワーク&ライフハックを行った内容を紹介したいと思います。

一緒に飲みに行きたい!

※ここで紹介する件は、2019年12月頃のことで、今はコロナのため、会社として飲み会は禁止されています。

Acroは、社員同士で夕食や飲みに行く機会が多く、私が所属するグループの上司もよく飲みに行っています。
ですが、私は上司と一緒に行く機会が減っていました。

そのため、何かしらの方法で「私も一緒に飲みに行きたい」という思いを上司に伝えられないかと考えました。

そこで目を付けたのが、AcroのLINEグループです。
Acroでは、社員の日常を共有する目的で、ランチや夕食などの様子をLINEに投稿する文化が根付いています。
やるなら面白く盛り上がりそうな方法でできないかと思い、LINEで投稿されてくる写真をうまく活用して、自動で上司にメッセージを送れないかと考えました。

調べてみたところ、LINE BotAmazon Rekognition(画像解析サービス)でできそうでしたので、それを使って一気に作ってみてました。

f:id:acro-engineer:20200331183152p:plain:w400

飲みに行ってそうな時間帯に上司が映っている写真が流れてきたら、何かしら返信する、というBotです。
Amazon Rekognition(画像解析サービス)は、思っていたよりも簡単に使えて、週末4日くらいで上記ができました。

Botのおかげもあり、一緒に飲みに行く機会も増えました^^
(直接伝えにくかったわけではないですよ。)

また、以下のような写真にも反応して、Bot自体を楽しむことも増え、盛り上げにもなっています^^
f:id:acro-engineer:20200331183210p:plain:w400
(社員旅行で酔いつぶれているときの1シーン)

笑顔で一日をスタート!

次は「笑顔で一日をスタートする」ために取り組みました。

Acroでは、朝のミーティングをチームごとに毎日行っていて、その時にチームの写真をLINEに投稿しています。
これもみんなで共有するというAcroの文化の一つです。
その写真を見て、一日の最初は笑顔で始めたいよね、という声も出てきていました。

上に書いたLINE Botがここでも使えそうと思いました。

今度は、「笑顔」がキーポイントになりますが、これもAmazon Rekognitionで実現できました。
いい笑顔の人には「褒めの言葉」を、笑顔でない人には「声かけ」をするようにしました。

f:id:acro-engineer:20200331183231p:plain:w400
f:id:acro-engineer:20200331183246p:plain:w400

これにより、みんな笑顔で始めようと意識したり、お互いにコミュニケーションも増えました。

今回は、対象者も多くなり、写真の構成も複雑になるため、社員からもいくつか要望があり、細かいチューニングもしています。
(運用するって、やっぱり大変ですね^^)

やってみて感じたこと

このように、LINE BotAWSのサービスを組み合わせることで、これまで開発がメインではなかった私でも、効果を発揮するサービスを作ることができました。

この一連の流れで大事だと思ったのは、「こんなことをしたい(要求)」からスタートすることでした。
これがあったから、手段にハマることなく、要求の実現にフォーカスし、最速でサービスを作ることができたんだと思います。
(実際、思った以上に受けてもらえたので、私自身驚いています^^)

Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

顧客のビジネスをインフラから加速するエンジニア募集! - Acroquest Technology株式会社のインフラエンジニアの求人 - Wantedlywww.wantedly.com

ANGEL Dojo最終発表で「アライアンス賞」を受賞しました!

こんにちは!
2年目エンジニアの古賀です。

先日ブログで紹介したANGEL Dojoですが、 2020年3月6日、最終発表があり、AWSの審査員の方々が選ぶ「アライアンス賞」を受賞しました!
上位3チームに選ばれると貰える賞の1つで、 今回がんばってきたことが1つの形になって、とても嬉しいです。
アライアンス賞の詳細は後ほど^^

※ANGEL Dojo とは、AWS様主催の疑似プロジェクトを通して、 クラウド開発力とAmazonの文化を学び、ビジネスで日本を元気にしよう! という企画です。
 詳細は、以前のブログ(http://acro-engineer.hatenablog.com/entry/2020/02/21/170000)を是非読んでください。
acro-engineer.hatenablog.com

会議の"質"を向上させる HuNam

私たちのチームが何をつくっていたのかというと、会議の"質"を向上させるためのサービス「HuNam」です!
※HuNam(ヒューナム)という名前は社内公募で決まりました。Human Nature Meeting の略で、人間の本質、人間らしい、といった意味合いです。

日本中にあるとされるムダな会議を、生産的かつ心理的安全性の高い、会議の"質"が高い状態にしたい、という思いでこのサービスを作りました!

会議の参加者が、以下のようなHuNam画面を見ることで、自分の行動をその場で改善し、自律的に会議の"質"を向上させていくことができます。

f:id:acro-engineer:20200308144735p:plain:w400
HuNamの画面

最後まで楽しみながらやりきりました!

発表は、コロナウイルスの影響で、完全リモートで行われました。
リモートの分、どう発表したらインパクトが残せるか試行錯誤した結果、プレゼンをライブ中継しました。

少しトラブルもありましたが、プレゼン形式にしたぶん、プレゼンの臨場感や勢いをアピールできた気がします!

ちなみに、今回我々が作ったサービスは、会議を効率化するためのサービスなので、今後Web対応して、リモートでも使えるようにしたいですね^^

f:id:acro-engineer:20200308064158j:plain:w400
プレゼンの様子

f:id:acro-engineer:20200308064227j:plain:w400
配信風景

アライアンス賞とは?

最終発表を聞いた、AWSの審査員の方々が、以下の観点で選んでくださった賞です。

アライアンス賞
• Working Backwards に沿った企画ができているか
• ビジネス的に興味深い/価値がある内容か
• ソリューション全体の完成度

サービスのコンセプトや、技術面までを総合して選んでくださったようです。
特に今回は、「何をしたらお客様は嬉しいのか」というところを、一生懸命考えたので、そこをしっかり評価して頂き、本当にうれしいです!!

また上位3チームに選ばれたので、2020/3/25に開催される AWS Partner Summit Tokyo で発表するチャンスを頂きました。
頑張って作ったサービスを多くの人に見て頂ける場なので、最後までやり切り、より良いものにしたいです!

f:id:acro-engineer:20200308145817p:plain:w400
アライアンス賞を受賞

f:id:acro-engineer:20200308064345j:plain:w400
受賞を喜ぶAcro ANGEL チームのメンバー

Still Day One

今回のANGEL Dojoをきっかけに、お客様視点に立つことや、クラウド開発のイロハを学ぶことができ、とても貴重な経験でした。
企画してくださったAWS様、支えてくれた先輩方、本当にありがとうございました!

また何より、今回のANGEL Dojoに送り出してくれた社長・副社長に受賞の報告ができ、喜んでもらえたので、嬉しかったです。
最後まで応援してくださり、ありがとうございました!

最後に、今回のANGEL Dojoの企画者の方からお祝いのメッセージと共に頂いた、以下の言葉を紹介したいと思います。

'Still Day One'

Amazonの企業理念で、直訳すると「まだ1日目」。意味としては、「毎日が新しい挑戦の始まり」というところでしょうか。
いい言葉ですね。
よりよいエンジニアになれるよう、謙虚に、チャレンジしていきたいと思います!

技術的な詳細な内容は、また後日ブログにする予定なので、お楽しみに!


Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 

少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

Java/PythonでモダンなWeb開発をしたいエンジニアWanted! - Wantedlywww.wantedly.com



AWS主催「ANGEL Dojo」へのチャレンジ & 中間発表で1位になりました!!

皆さん、こんにちは!
最近機械学習エンジニアからDevOpsエンジニアにキャリアチェンジをしつつある渡邊(@move_fastest)です。
月日が流れるのが早く、昨年3月に入社して、早くも1年が経とうとしています。

実は昨年の年末からAWSジャパン様で企画された、「ANGEL Dojo」に会社の若手を代表して参加させて頂いています!
※ANGEL は APN((AWS Partner Network)Next Generation Engineer Leaders の略

2/14(金)に中間発表を終え、ANGEL Dojoも終盤に差し迫ってきたということで、これまで取り組んできたことを振り返ってみたいと思います!

クラウド開発で日本を元気にする ANGEL Dojo

AWS様公式のHPに「ANGEL Dojo」の定義が書いてあったので引用します。

ANGEL Dojoでは次世代を担うAPNの若手のエンジニアの方々に、擬似プロジェクトを通じてアジャイル、DevOps、モダンなアプリケーション開発などのクラウドネイティブな手法と、様々なInnovationを作ってきたAmazonの文化と考え方を体験いただくことで、お客様にクラウドの価値を100%届けるための基礎的なスキルを実践を通して身につけていただきます。参加者の皆様はここで培ったスキルと、各パートナーの皆様がお持ちのそれぞれの強みを活かすことでお客様のビジネスを成功に導き、日本のITや経済をさらに成長させる主役、すなわち「APN Next Generation Engineer Leader」になっていただきます。

要するに、AWS様主催の疑似プロジェクトを通して、クラウド開発力とAmazonの文化を学び、ビジネスで日本を元気にしよう! という企画です。
IT経験1-3年以内の人が対象で、3月初旬に最終発表があります!

ちなみに、ANGEL Dojoの企画が始まるきっかけとなったのは、ある日AWSのマネージャーの方が「日本を元気にしたい!」と言い出したのがきっかけだそうです。
「日本を元気にしたい!」と思うだけではなく、それを実際に企画してしまう行動力、そしてそれを許容する柔軟な組織文化が凄いなぁと思いつつ、感謝の気持ちでいっぱいです。

↓詳しくはこちらをご覧下さい↓
「日本を元気にする」APN Next Generation Engineer Leaders(ANGEL) Dojo のご紹介


知らないことだらけの疑似プロジェクト

サービスの企画から検討するのって楽しい、けど、難しい

年明け(1/6(月))からプロジェクトがスタートし、最初の2週間は企画のフェーズでした。
"Working Backwards"(逆向き解決法)と呼ばれる、Amazonが実際にサービス企画をする際に使用するフレームワークで、お客様を起点にサービスの企画を行い、それをもとにPR(プレスリリース)を作成しました。

一からサービスを企画するのは想像していたよりもずっと難しかったです。
気づくといつも「お客様が必要としているもの」ではなく、「自分達が作りたいもの」になってしまっていました笑。
そんなとき、「自分達が企画するサービスは、本当にお客様が求めているものなのか?」 この問いに何回も立ち返り、メンバ同士で議論することで、徐々に、お客様が求めているもの(課題)やそれを解決するサービスに対する理解が深まりました。

結果として、(多くの時間を費やしたお陰もあり、)サービス内容をブラッシュアップすることができたので、非常に合理的なフレームワークだと感じました。
何を作っているかというと、みなさんの会社でも(おそらく)非効率になりがちな会議を効率化するためのサービスです。詳細は今後のお楽しみに♪

f:id:acro-engineer:20200219022002p:plain:w400
サービス企画風景

良いサービスを開発したい!

1月終盤より、企画したサービスをもとに、アーキテクチャを考え、実装に入ります。
しかし、自分達で考えたアーキテクチャ、DBスキーマ、レポジトリがナンセンスで、何度もリファクタをする羽目に・・・
普段のプロジェクトでは上司が設計してくれている部分なので、改めて無駄がなく整理されたアーキテクチャを考えてくれている上司の偉大さが身に染みました。ありがたや・・・

本当は1月中にMVP(Minimum Viable Product)を社内リリースして運用してみたかったのですが、間に合わず断念。
その後も中間発表の準備に加え、セキュリティ観点での課題も見つかり、まだ社内リリースができていません。
早く社内にリリースして実際に使ってもらいたいです。

ということで、現在も機能の作成は続けています、正直トライ&エラーの繰り返しですが、より良いサービスを作りたいという思いが強いので、とても楽しい時間です!

f:id:acro-engineer:20200219023423p:plain:w400
もくもくと実装している風景

中間発表で1位に選んで頂きました!

最終発表は3月初旬ですが、2/14(金)に中間発表がありました!
発表は午後からだったのですが、発表で使用するデモ動画、発表資料の修正を当日のランチ頃まで行っており、かなりドタバタしてしまいました。

中間発表では、全15チームが揃って発表することもあり、そこで初めて他の参加企業が作ろうとしているサービスを知ることができました。
どの企業もWorking Backwardsでお客様が日頃感じる不満から逆算した、サービス内容だったので、聞いていて素直に、「このサービス欲しいなぁ」、「このサービスが実在したら、日頃困らなくなるなぁ」と納得させられるものがほとんどでした。

私達の発表では、実際に利用してもらうシーンを想定してもらうため、作成したサービスを使用したデモ動画を紹介しました。
苦労して作成したデモ動画が好評だったこともあり、ありがたいことに中間発表では参加者投票で1位を取ることができました。
ただ、どのチームのサービスも魅力的だったので、本番発表まで残すところ2週間弱、より良いサービスを作れるよう頑張ります!

f:id:acro-engineer:20200219025513j:plain:w400
アクロ発表者(古賀)

f:id:acro-engineer:20200219025655j:plain:w400
アクロ発表者(渡邊)
f:id:acro-engineer:20200219025728j:plain:w400
中間発表見事1位

周りの方々のサポートに感謝

このチャレンジをするにあたって、多くの方々のサポートがあります。
AWS様は、週2~3回の講義、ハンズオンなど多くの企画も実施して頂いており、とても勉強になっています。また、クラウド開発のアーキテクチャやお客様視点で考えるためのコツなど、アドバイスやレビューを何度も実施してもらっており、とても助かっています。本当にありがとうございます!

さらに、この企画は1チーム5人での参加が基本となっていますが、1社で5人というのはなかなか難しく「混合チームとして参加」という案で考えていた中、「どうせやるなら5人でやった方が良い」と送り出してくれた社長・副社長には感謝です!

このように、年始から始動し、色々な方のサポートの元開発を進めているサービスなので、世の中に役立つものとして今後公開できるようにしたいと考えています!
そして、最終発表では1位になって周りで支えてくれた人に恩返しがしたいので、最終発表の3/6(金)に向けて、ラストスパートをかけていきます!
(実は、上位のチームは AWS Partner Summit Tokyo で発表する機会を頂けるので、それもモチベーションになっています)

最終発表の結果もこのブログにて報告するつもりなので、みなさん、お楽しみに!!


Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 

少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

Java/PythonでモダンなWeb開発をしたいエンジニアWanted! - Wantedlywww.wantedly.com



Deep Java Library(DJL)を使ってみた

hayakawaです。
今回はJavaディープラーニングを実装できるOSSであるDeep Java Library(DJL)を使ってみました。

https://djl.ai/


ディープラーニングで何かをやるとしたら、現状ではPythonで開発するケースが多いですが、
システム全体としてはJavaで開発をしたいが、ディープラーニングの処理を利用したい場合、
これまでだと良いソリューションがなく、別サービスとしてAPI呼び出しをしたり、
JavaからPythonのプロセスを呼び出したりするようなことが必要でした。
ただこれだと、パフォーマンスが求められる場合、なかなか厳しいものがあります。

このOSSはそのようなケースで、Java上でのディープラーニング処理も実行できるようにすることを目指しているようです。

aws.amazon.com

Pythonで学習・モデル作成を行い、それをJavaで推論する、ということもできるようですが、
今回は、基本的な判定処理と学習処理を、Javaのサンプルコードから読み解いてみます。

判定処理

判定処理は、物体の種類と位置を検知する物体検知タスクのサンプルを見てみました。
プリトレーニングモデルを用いて、短いコードで判定を実現しています。

サンプル(ObjectDetetion.java)

    public static DetectedObjects predict() throws IOException, ModelException, TranslateException {
        Path imageFile = Paths.get("src/test/resources/dog_bike_car.jpg");
        BufferedImage img = BufferedImageUtils.fromFile(imageFile);

        Map<String, String> criteria = new ConcurrentHashMap<>();
        criteria.put("size", "512");
        criteria.put("backbone", "resnet50");
        criteria.put("flavor", "v1");
        criteria.put("dataset", "voc");

        try (ZooModel<BufferedImage, DetectedObjects> model =
                MxModelZoo.SSD.loadModel(criteria, new ProgressBar())) { //(1) 

            try (Predictor<BufferedImage, DetectedObjects> predictor = model.newPredictor()) { //(2)
                DetectedObjects detection = predictor.predict(img); //(3)
                saveBoundingBoxImage(img, detection);
                return detection;
            }
        }
    }
(1)モデルの読込み

モデルの読込みは

MxModelZoo.SSD.loadModel(criteria, new ProgressBar()))

というコードでやっています。

最初の MxModelZoo.SSD というところで、物体検知用のアルゴリズムであるSSDを指定し、
さらにSSDのバックボーンとなる画像判定モデルを何にするかを、
上のcriteriaというMapに詰めて指定して渡しています。
今回は"VOC"(PASCAL VOCのデータセット)で学習されたResNet50 v1のモデルを指定しています。

学習済みモデルは、名前の通りMXNet上の物がサポートされているようです。
AWSさんですし、MXNetになりますよね。

MxModelZooで指定できるモデルは以下のページに表で一覧されています。

djl/mxnet/mxnet-model-zoo at master · awslabs/djl · GitHub

表の各列の意味は次の通りです。

説明
Application 画像分類(Image Classification)やポーズ検知(Pose Estimation)などのタスクの種類。
Model Family SSDなどのモデルの分類名。この名前をMxModelZoo.~のところに指定します。
CriteriaとPossible values サンプルコードであったcriteriaに指定できる条件と値の組み合わせです。

今回やっている物体検知(Object Detection)は現在SSDのみをサポートしており、
バックボーンはVGGやMobileNetが使えるようです。

(2)判定器の生成
Predictor<BufferedImage, DetectedObjects> predictor = model.newPredictor()

で、新しい判定器を生成しています。

(3)画像の判定

メソッドの先頭の

Path imageFile = Paths.get("src/test/resources/dog_bike_car.jpg");
BufferedImage img = BufferedImageUtils.fromFile(imageFile);

で読み込んだ画像を、(2)で生成した判定器に

predictor.predict(img);

で渡し、さらに結果をsaveBoundingBoxImage()というprivateメソッドに渡して、
画像上に検知結果の名称と枠線を描画させています。

得られた画像が次のものです。

f:id:acro-engineer:20200214101006j:plain

リポジトリ内の djl/examples/src/test/resources/ ディレクトリに、
試し斬りに使える画像が置いてあるので、

Path imageFile = Paths.get("src/test/resources/dog_bike_car.jpg");

のところを書き換えて試してみましょう。

学習処理

学習の方は、伝統的なMNISTのサンプルがあったので試してみました。

サンプル(TrainMnist.java)

    public static ExampleTrainingResult runExample(String[] args)
            throws IOException, ParseException {
        Arguments arguments = Arguments.parseArgs(args);

        // Construct neural network
        Block block =
                new Mlp(
                        Mnist.IMAGE_HEIGHT * Mnist.IMAGE_WIDTH,
                        Mnist.NUM_CLASSES,
                        new int[] {128, 64}); //(1)

        try (Model model = Model.newInstance()) {
            model.setBlock(block); //(2)

            // get training and validation dataset
            RandomAccessDataset trainingSet = getDataset(Dataset.Usage.TRAIN, arguments);
            RandomAccessDataset validateSet = getDataset(Dataset.Usage.TEST, arguments); //(3)

            // setup training configuration
            DefaultTrainingConfig config = setupTrainingConfig(arguments); //(4)
            config.addTrainingListeners(
                    TrainingListener.Defaults.logging(
                            TrainMnist.class.getSimpleName(),
                            arguments.getBatchSize(),
                            (int) trainingSet.getNumIterations(),
                            (int) validateSet.getNumIterations(),
                            arguments.getOutputDir()));

            ExampleTrainingResult result;
            try (Trainer trainer = model.newTrainer(config)) { //(5)
                trainer.setMetrics(new Metrics());

                /*
                 * MNIST is 28x28 grayscale image and pre processed into 28 * 28 NDArray.
                 * 1st axis is batch axis, we can use 1 for initialization.
                 */
                Shape inputShape = new Shape(1, Mnist.IMAGE_HEIGHT * Mnist.IMAGE_WIDTH);

                // initialize trainer with proper input shape
                trainer.initialize(inputShape);

                TrainingUtils.fit( //(6)
                        trainer,
                        arguments.getEpoch(),
                        trainingSet,
                        validateSet,
                        arguments.getOutputDir(),
                        "mlp");

                result = new ExampleTrainingResult(trainer);
            }
            model.save(Paths.get(arguments.getOutputDir()), "mlp"); //(7)
            return result;
        }
    }
(1) レイヤ構造を定義

ニューラルネットワークのレイヤ構造を、MLPというクラスに生成させています。
MLPクラスのコードはこちらです。
お手軽に多層パーセプトロンを作ってくれるようです。中は次のようになっていました。

public Mlp(int width, int height) {
    add(Blocks.batchFlattenBlock(width * (long) height))
            .add(new Linear.Builder().setOutChannels(128).build())
            .add(Activation.reluBlock())
            .add(new Linear.Builder().setOutChannels(64).build())
            .add(Activation.reluBlock())
            .add(new Linear.Builder().setOutChannels(10).build());
}

width×heightの入力を受け取り、各層で128個、64個、10個の出力をする層を重ねたネットワークを構築しているようです。
層の内容を変えたければこのクラスでやっているようにadd()メソッドで積み重ねて作れます。

(2) モデルの生成

(1)のレイヤ定義を使って

try (Model model = Model.newInstance()) {
    model.setBlock(block);

で初期状態のモデルを生成しています。

(3) データの準備

getDataset()というprivateメソッドを呼び出して、MNIST用のデータを取得します。
Argument(プログラム引数)を渡しているのは、引数で指定したエポック数とバッチサイズに応じたデータ数を引っ張ってくるためのようです。

RandomAccessDataset trainingSet = getDataset(Dataset.Usage.TRAIN, arguments);
RandomAccessDataset validateSet = getDataset(Dataset.Usage.TEST, arguments);

getDataset()の内部では、 Mnist.builder() という組み込みのMNISTデータロード用クラスにデータを作らせていました。

(4) 学習の設定

setupTrainingConfig()というprivateメソッドの内部で、

return new DefaultTrainingConfig(Loss.softmaxCrossEntropyLoss())
        .addEvaluator(new Accuracy())
        .setBatchSize(arguments.getBatchSize())
        .optDevices(Device.getDevices(arguments.getMaxGpus()));

という処理で学習用の設定インスタンスを生成しています。
プログラム引数のバッチサイズや利用してよいGPU数などをセットし、Softmax関数、クロスエントロピー誤差を指定しています。

(5) 学習器の初期化

(4)で生成した環境設定で、学習器を生成しています。

Trainer trainer = model.newTrainer(config))
(6) 学習開始

学習器やデータを渡して、実際に学習を開始します。

TrainingUtils.fit(
        trainer,
        arguments.getEpoch(),
        trainingSet,
        validateSet,
        arguments.getOutputDir(),
        "mlp");
(7) モデルの保存

model.save()を呼ぶとファイルに学習済みモデルを保存できます。

model.save(Paths.get(arguments.getOutputDir()), "mlp");

感想

基本的な判定と学習を見てみましたが、APIの構成内容がオーソドックスで名前にクセも無いため、
他のディープラーニングフレームワークを知っていれば習得は速そうです。

またGPUは勝手に見つけて勝手に使ってくれるらしく楽です。

OpenCVなどを用いる画像処理ライブラリは、DJL側でラッパーを用意しており、
基本的な操作であれば独自にOpenCVを触らないでよさそうです。

上で紹介した以外のサンプルも同じディレクトリに配置されており、
基本的にはサンプルを真似して使えば一通りのことはできそうだと感じました。
Java上のディープラーニングライブラリとしては、良い候補になりそうです。

Acroquest Technologyでは、キャリア採用を行っています。


  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
Kaggle Masterと働きたい尖ったエンジニアWanted! - Acroquest Technology株式会社のデータサイエンティストの求人 - Wantedlywww.wantedly.com