iOSDCでiOSアプリのリニューアルについて話をしてきました

RettyでiOSをメインに開発とかマネジメントをしているkosakoです。 先日iOSDC 短期間でやり遂げるための、 大規模リニューアルの進め方 というタイトルで話をしてきましたので、レポートとかネットでの反応に応えてみます。

f:id:rettydev:20170926145915j:plain

提出したCfPとスライド

Rettyでは2年半ぶりに大規模なリニューアルを行っています。 まだリリースはされていませんが、言語をObjective-cからswift4.0へ移行したり、アーキテクチャの刷新も短期間で行おうとしています。 やり遂げるためにどんなことをやっているのか、リニューアルなど大きな開発で起きる仕様の変更による手戻りの発生への対応、全員の共通認識をどうやって合わせてチームビルディングを行っていくかなどをお話します。

ネットの反応

概ね好評だったようでよかったです。 サグラダファミリアと一日8時間コードがかけると思っているは結構うけたようでよかったです。

Design Docや自前のHIGなどへの取り組みも興味を持っていただけたようです。

テストについて

  • QAさんによるテストやテスト仕様書の話をしなかったので、自動テストだけでいくと思われてたかもしれません
  • 仕様書とテスト仕様書はちゃんと作って、継続的な運用にしていく予定です

感想

会場がすごく広くて、自分が発表したA会場は500人ぐらいはいるかなり大きな会場でした。 4会場あって、様々な発表があり視点が広がって非常に楽しい時間でした。 リニューアル関係の話も結構あって、いろんな会社がいろんな取り組みをしているのが興味深かったです。

来年はリニューアルしたアプリでの具体的な成果を発表できたらと思っています。

最後に。今年はストラップスポンサーとしても参加していました。 今年のオープニングは三石 琴乃さんによる某アニメ風になっております。弊社も読み上げられていますので見てみてください。

カラムナフォーマットのきほん 〜データウェアハウスを支える技術〜

こんにちは、Retty.Inc ソフトウェアエンジニア兼データサイエンティストのchie(@chie8842)です。 好きなたべものは焼肉とみかんです。

現在Rettyでは、次世代分析基盤を構築しています。Rettyでは、サービス拡大に伴いログの急増や分析需要の拡大が見込まれるため、高いスループットとコストパフォーマンスを両立する、スケールするアーキテクチャ設計が求められています。

今回は、こうしたスケールするアーキテクチャ設計の実現のために理解しておくべきDWHのコア技術の一つである、カラムナフォーマットに焦点を当てて紹介します。

はじめに - カラムナフォーマットとは

カラムナフォーマットとは、データベースの分析用途に利用されるファイルフォーマットの種類の一つです。大量のデータを扱う際に効率的に圧縮してストレージコストを下げたり、計算時に必要なデータだけを取り出して計算コストを小さくできる設計がされています。
本稿では、分析基盤で利用されるファイルフォーマットの概要を紹介し、 そのあとに、カラムナフォーマットにおける符号化方式、データモデル、ファイルフォーマットについて説明しようと思います。

分析基盤で利用されるフォーマット

最近は分析基盤用途として、Hive、Presto、Sparkといった並列分散処理プロダクトやそれらのマネージドシステムであるAmazonのEMRやAthena、GCPのDataProc、そしてフルマネージドなBigQueryやRedShiftが利用されるようになりました。

これらのプロダクトで取り扱えるフォーマットは、大きく以下3つに分けることができます。

  • テキストフォーマット(例:CSVJSON
  • 行指向フォーマット(例:AVRO)
  • 列指向(カラムナ)フォーマット(例:Parquet、ORC)1

CSVJSONといったテキストフォーマットは、人間からの可視性が高い、アプリケーション連携がやりやすいというメリットがあります。しかしながら、データベース用途のフォーマットとしては、人間からの可視性よりも、保存時の圧縮効率や機械による処理のしやすさを追求する必要があります。データベース用途に向いているフォーマットの種類としては、行指向フォーマットと列指向フォーマットがあります。
行指向フォーマットと列指向フォーマットの違いは、データの格納方式です。
行指向フォーマットは、行方向に連続してデータを格納するため、一つの行をまとめて操作することの多いOLTP処理に向いています。従来のデータベースはもともとこの行指向フォーマットが利用されてきました。
ストレージ技術などの発展により、DWH用途での利用を行うようになって、注目されるようになったのが列指向フォーマットです。列指向フォーマットは、列方向に連続してデータを格納する方式で、列単位でデータを取り出す分析用途に向いています。

主要なOSSのカラムナフォーマットのライブラリとしては、ParquetとORCがあります。
ParquetはTwitter社とCloudera社が、2010年のGoogleの論文Dremel: Interactive Analysis of Web-Scale Datasets(以下Dremel Paper)におけるデータレイアウトに関する内容をOSS実装したもので、ORCはもとはApache Hiveのためのフォーマットとして実装されたという背景の違いがあります。

カラムナフォーマットにおける符号化方式の基礎

カラムナフォーマットでは、データ型やカーディナリティ等の特性に応じて、様々な符号化方式から決定木等によって各列に最適なエンコード方式を選択します。これらの符号化技術自体は、行指向フォーマットでも利用されるものですが、カラムナフォーマットでは、型が同じデータが並んだり、規則的にインクリメントするデータが並ぶなど、符号化によるデータ圧縮が効きやすいというメリットがあります。

ここで符号化方式の一部を紹介します。

Null Suppression

これは、nullの多い列の圧縮に大きく寄与する技術です。nullの値を埋め込む代わりに、どこにいくつnullが存在するかの情報を保持することで、データサイズを小さくします。

Dictionary Encoding

以下の図のように、辞書情報を作成して、その辞書情報を利用して符号化する方式です。
データのカーディナリティの低いString形式のデータに有効ですが、データのカーディナリティが高くなると、辞書情報が肥大化して圧縮率は低くなります。 スクリーンショット 2017-06-05 2.25.22.png

Run-Length Encoding(RLE)

RLEは、繰り返しが続くデータに対して、下図のように繰り返し項目をまとめて保存する方法です。
繰り返しの長さが長くなるほど、圧縮率が高くなる特徴があります。
スクリーンショット 2017-06-05 2.24.41.png

Delta Encoding

Delta EncodingはTimestamp型などのインクリメンタルなデータで効果的なエンコード方式です。
Delta Encodingでは、まず最初に参照値を決め、それ以外の値をブロックに分けます。
それぞれのデータにおいて、一つ左隣の値との差分をとります。
この値の最も小さい値を使って標準化し、最後にビット数に直します。
図の例だと、最初の112bitから40bitと、3分の1程度に圧縮されていますが、データ量が多くなるほど圧縮率が高くなります。^2 スクリーンショット 2017-06-05 2.28.10.png

Bit-Vector Encoding

Bit-Vector Encodingは、Boolean型などの限られた値をとるデータに用いるエンコード方式です。
ある値と合致するかどうかを1と0で表したものを保持します。データのカーディナリティが著しく低い場合に有効です。
スクリーンショット 2017-06-05 2.34.59.png

Dremelのデータモデル

次に、BigQueryやParquetで実装されている、Dremelのデータモデルについて紹介します。
カラムナフォーマットについて書かれた論文に、GoogleのDremel Paperがあります。BigQueryはこのDremelの外部公開版であり、また、Parquetもこの論文をOSS実装したものです。
Dremelの新規性として、ネストされたデータに対応できる柔軟なデータモデルが挙げられます。下図(Dremel PaperのFigure1を引用)の左のように、record orientedな方式では、ネストされた型や特性の異なるデータが、並ぶ形となり、上記で述べたエンコードの効果を受けにくく、またネストされた一部のフィールドを利用する際にも、不必要なフィールドも含めてデコードする必要があります。対して右のcolumn orientedな方式では、同じフィールドのデータをまとめて保存でき、ネストされたデータの一部を利用する際には、木構造をたどることで必要なフィールドのみを抽出することができます。

スクリーンショット 2017-06-05 2.49.04.png

しかし、1つの行に何回同じフィールドが出現するかわからないようなrepetableなデータを扱う場合、そのデータ構造を欠落させることなく小さいオーバヘッドで木構造のデータを保持するための工夫が必要となります。
Dremelでは、下図(Dremel PaperのFigure2,3を引用)のように、反復レベル(Figure3の表におけるr列)と定義レベル(Figure3におけるd列)をもつことで、データ構造を復元できるようにしています。
スクリーンショット 2017-06-05 2.49.18.png 反復レベルと定義レベルの説明は以下のとおりです。

  • 反復レベル
    • あるレコードにおいてそのフィールドが初めて出現する場合は0とする
    • 2つ目以降については、親フィールド配下での反復回数を表す
  • 定義レベル
    • 一意でないフィールドの階層を表す

BigQueryでは、repetableなデータで構成されるデータを対象とした分析を行う場合などにこのデータモデルによるクエリ速度向上が見込まれます。

ただし、私個人の意見としては、Parquetの場合はクエリエンジン側がこのようなデータモデルに対応したものである必要があることもあり、現状でこのデータモデルの恩恵が生かされている例は少ないのではないかと考えています。

ファイルフォーマット

ParquetやORCでは、分散処理を行うことを前提として、Encoding/Compressionの単位、IOの単位、MapReduceの単位で処理しやすいようにデータが分割配置の工夫がされています。
以下の図はParquetのファイルフォーマットの説明図です。
スクリーンショット 2017-06-05 2.51.28.png File/Row Group/Column/Pageといった単位でデータを分割配置されていることがわかります。
また、上記の分割単位ごとに、ヘッダ/フッタにメタ情報を持っています。メタ情報の内容としては、

  • レコード数
  • データの最大値/最小値
  • メモリに展開した際のサイズ

などがあげられます。
メタデータを利用することで、データを読み込む際に、必要のないデータを読み飛ばすことができます。たとえば、

SELECT tbl1.colA, tbl2.colB FROM tbl1 JOIN tbl2 ON tbl1.colA == tbl2.colA;

といったクエリの場合、最終的に必要となるのは、tbl1のcolA、tbl2のcolAとcolBだけとなります。ParquetやORCを利用すると、ファイルスキャンの段階で、これらの必要なデータのみを抽出することが可能になります。
ただし、メタデータによる最適化が利用されるかどうかはクエリエンジンのオプティマイザによって作られる実行プランに依存します。

分析基盤におけるフォーマットの選定について

ここまでカラムナフォーマットのアーキテクチャと分析基盤における有効性についてざっくり説明しました。
上述したとおり、カラムナフォーマットにはクエリパフォーマンスをあげるための仕掛けが施されています。ただし、フォーマットはあくまで最適化しやすいデータ形式であって、それらを活かし切るかどうかは実際に処理を行うクエリエンジン側に依存します。
データの特性や利用するプロダクト、実行するクエリパターンによって、フォーマットを適切に使い分けることができるとよいと考えます。

まとめ

以上、目新しい技術というわけではないですが、分析基盤の縁の下の力持ち的なカラムナフォーマットの技術について、淡々と述べてみました。

尚、本稿の内容については、5/18のBIGDATA-JAWSにて、「カラムナフォーマットのきほん」というタイトルで発表をさせていただきました。

speakerdeck.com

Rettyでは、DWH技術を学びたい技術者を募集しています。
www.wantedly.com よろしくお願いいたします!

参考資料


  1. BigQueryとRedShiftも内部的にカラムナフォーマットが用いられている。

How to make a machine learning infrastructure that supports 22 million users

Original article (日本語): http://qiita.com/taru0216/items/dda1f9f11397f811e98a

Retty “How to make a machine learning infrastructure that supports 22 million users”

f:id:rettydev:20170530150841p:plain

Hello, everyone. My name is Taruishi, and I’m the CTO at Retty.

There’s not much time left until the year is over. Have you already decided how you’ll spend the rest of the year?

The number of engineers at Retty have nearly doubled in the past year. As a result, we have enough people to who can write articles which allows us to participate in this year’s Advent Calendar. I’m pleased to see that everyone seems to be having fun doing it.

http://qiita.com/advent-calendar/2016/retty

For the final post for this year’s Retty Advent Calendar I had considered writing about what I did over this past year at Retty, but that’s not very unique or interesting. Instead, I decided to write about something fairly crazy that I did this year.

That is, “Building Retty’s machine learning infrastructure using parts purchased while walking around Akihabara”.

※ This is not a post about machine learning techniques or history. If that’s what you’re looking for, then I recommend checking out Rakuten Institute of Technology’s Mori’s Advent Calendar (日本語) or check out this summary (日本語) and start reading from there.
※ This post has a lot of logos and images to make it easier to read. The names of all software, products, companies, stores, and their logos, are copyrighted by their respective owners.
※ This article was written with the intent of being as accurate as possible, but no guarantees can be made.

Overview of Retty’s machine learning infrastructure system architecture

First, I would like to explain the architecture of Retty’s machine learning infrastructure.

We have 5 ATX-sized machines running on Intel processors, all equipped with 2 consumer-grade NVIDIA GPUs.

f:id:rettydev:20170530151144p:plain

All machines are running a Docker container with SSH enabled. The GPU can be used by logging into any of the machines. The home directory of the Docker container is shared through NFS so you have access to the same data no matter what machine you are using.

From the machine learning engineer’s point of view, all 10 GPUs are part of a “preemptible container1 where you can access the same files no matter where you are logged in”.

Examples of techniques developed using Retty’s machine learning infrastructure

I’d like to introduce some of the stuff that has been developed using Retty’s machine learning infrastructure now.

Image Categorization

A classic machine learning problem. At Retty, we separate images into 4 different categories: “food”, “restaurant exterior”, “restaurant interior”, and “menu”.

f:id:rettydev:20170530151348p:plain

Source: https://retty.me/area/PRE13/ARE14/SUB1401/100001178822/photos/ (日本語)

This was all done manually until we were able to come up with a CNN model that produced results accurate enough for us to be able to put it into production.

Tagging Food Pictures

Using image categorization, we were able to create techniques to tag what kind of food is displayed in a picture. As you can see below, the image tagged “pancake” is automatically being chosen to represent the restaurant in the search results.

Before

Search keyword: Pancake

After

Search keyword: Pancake

Source: https://retty.me/area/PRE01/ARE164/LCAT9/CAT161/ (日本語)

Previously only one pre-selected image would be displayed to represent the restaurant in the search results. But, using the above “Omurice and Pancakes” restaurant as an example, some restaurants are known for more than just one type of food. In this case, since the omurice picture would normally be displayed, users searching for pancakes would end up seeing omurice instead.

Using the image tagging technique, we are now able to show omurice to people searching for omurice, and pancakes to users who are searching for pancakes.

Super Resolution (Making images clearer)

Super resolution is the process of making an image a higher resolution and then converting it into an even clearer picture.

Up until recently it was common to filter the image based on edge enhancement, but in recent years it’s there has been great development of techniques using deep learning to create super resolution images.

We also tried our hand at using deep learning to create super resolution images here at Retty.

f:id:rettydev:20170530151508p:plain

(Image from restaurant: https://retty.me/area/PRE13/ARE1/SUB101/100000868744/ (日本語))

It might be difficult to tell the difference between the two methods from just the side by side embedded image, so let’s take a closer look.

f:id:rettydev:20170530151624p:plain

f:id:rettydev:20170530151627p:plain

※ This technique could possibly be used to improve the compression ratio of lossy images. I think it’s worth keeping an eye on.

In addition, we’ve had several people develop about 30 new techniques to solve such problems as extracting unique characteristics about a restaurant based on user reviews (日本語) and detecting high quality images that look like they were taken with a DSLR camera (日本語). When I say new techniques, I mostly mean it in the way that that it takes our company some time to get caught up with all of the new papers coming out.

Machine learning web apps have also been developed to make it easier for non-machine learning engineers to take advantage of the new techniques.

f:id:rettydev:20170530151706p:plain

They are lovingly known as ICACHAN (for image classification), MICANCNN (for image modification), and TACOCNN (for natural language processing).

6 reasons we built the machine learning infrastructure ourselves

Retty has run its service on AWS from launch all the way up until last year. Starting with this year, we have started using other cloud services such as Google’s BigQuery and Microsoft’s Azure, but we hadn’t attempted anything outside of the cloud.

There are reasons why I decided that it was a good idea for Retty to build its own infrastructure with parts we bought ourselves.

  • A GPU is required for deep learning
  • Our deep learning engineers had sticker shock after seeing the price of cloud instances with GPUs
  • Since there was little information available about the efficiency of the GPUs, it was hard to tell how much it would cost to use for machine learning
  • Our engineers got too caught up in trying to figure out what instance would perform the best for a given algorithm based various bottlenecks that may be present such as CPU, GPU, memory, IO, or network, which meant less time spent working on the actual machine learning tasks
  • Since we would be SSHing into the machines for development work, the latency between the cloud service and our office did not help with productivity
  • Since the price of GPUs get cheaper by the month, I thought maybe it would be possible to build a low cost system by buying only the parts required at the time they were needed

There were various reasons why I chose to build our own system in addition to those already listed above, but if I had to choose one reason in particular, it would be that we wanted to create an environment that the engineers could freely use at any moment. Now, with the creation of our own system, there is always at least 1 person using the GPUs at any given time of the day.

How the machine learning infrastructure was implemented

When designing our system, requirements for future development had to be taken into consideration.

  • A system that could easily be improved and scale to the current demands
  • The data and environment should be prepared in such a way that machine learning tasks can be started immediately without issue
  • When the machines are reinstalled each iteration, the engineers’ data should still remain untouched
  • In order to get the best return on our investment and increase the amount of techniques available to us, another goal was to use the cheapest parts and to use open source software and techniques

After iterating through PDCA many times, our architecture ended up looking like this.

f:id:rettydev:20170530152137p:plain

  • juju for configuration management
  • MaaS for automatic OS deployment and AWS spot instancing
  • ceph for distributed storage system
  • corosync/pacemaker for the NFS cluster
  • A Docker image including all software required for machine learning
  • Kubernetes for VXLAN management and Docker container scheduling

juju for configuration management

juju is an infrastructure configuration management tool. There are other similar tools out there like Ansible, Chef, and Puppet. juju is available as a standard tool within Ubuntu and can be instance bootstrapped which works very well with the previously mentioned MaaS software, and is also easy to scale. For example, you can add 48 machine learning machines using the following command2:

juju add-unit -n48 akiba

※This is just my personal opinion, but I think that juju is much more easier to use than other similar tools. The approach in regards to ease of use might just be the way of Debian-based distributions, similar to apt.

Retty’s machine learning infrastructure makes heavy use of Docker (Kubernetes). Since a large majority of the management is being done through Docker, juju is being used when creating the Docker (Kubernetes) environment.

MaaS for automatic OS deployment and AWS spot instancing

MaaS is an OS deployment system that is capable of automatically installing an OS from a bare metal environment. Using PXE booting, it’s possible to automatically install Ubuntu on top of the bare hardware. It a fully featured system that has other features such as software RAID and bonding. We use MaaS on our custom built machine learning cluster.

juju can also be used with not just MaaS, but also cloud services such as AWS, Azure, and GCP. When more GPU power is required than is available within our cluster, we scale using the cloud’s spot resource3.

ceph for distributed storage system

f:id:rettydev:20170530152251p:plain

ceph is a distributed storage system that allows for one virtual storage system over the network to be used across multiple servers. A common use for ceph is as a distributed block device, which is also how we’re using it in the Retty machine learning infrastructure.

(We’ve also started using the recently released stable version of cephfs lately.)

corosync/pacemaker for the NFS cluster

Source: http://clusterlabs.org/

In order to create a NFS server that does remains running during machine maintenance, ceph acts as the block device while corosync and pacemaker are used to create a single master and failover NFS server.

A Docker image including all software required for machine learning

In addition to tensorflow and chainer, we require other libraries like genism, mecab (日本語), cabocha (日本語), word2vec, fastText, keras, etc. To ease the pain of having to install all of the required libraries, we’ve created a Docker image that can automatically install everything. As long as NVIDIA drivers are installed on the host machine, you can run a command such as

docker run --privileged -it --rm 192.168.0.1/retty-runtime-anaconda

and it will set up a machine learning environment just like that. Since the Docker image is 10gb (5gb compressed), we use a Private Docker Registry on our servers and pull the image directly from there. What used to take about 70 minutes to complete now takes a mere 5 minutes.

(Since the machine learning Docker image can also work in a CPU-only environment, it’s possible to do this all from a Mac as well.)

Kubernetes for VXLAN management and Docker container scheduling

Kubernetes uses the SSH-enabled Docker images to run on each individual machine. It is running through a simple VXLAN virtual network created with flannel. Home Docker is running on all of the host machines, so the machine learning engineers are able to log into any machine. The home directory is setup using the previously mentioned NFS server with failover enabled. This setup allows the engineers to have the same files no matter what machine they are using at the time.

There is also Docker running within Kubernetes. This allows the machine learning engineers to easily run simple Docker features through the command line, such as docker-compose.

The techniques behind the Retty machine learning infrastructure

In order to increase performance and productivity, various techniques are in place for the Retty machine learning infrastructure.

Disk Performance

All machines have 6 separate SSDs, bringing us to a total of 30 SSDs being used to create a distributed storage system. Using iotop to measure performance and ceph to rebalance the data (data management), 1 node can reach a max throughput of up to 450 MB/s (3.6Gbps). I think there’s still more room for improvement, but for now it’s good enough for our purposes.

I should also point out that the motherboard that we use in our machines (z170 chipset) has only 6 SATA ports. Since all 6 ports are dedicated to ceph, the systems are booted using an SSD connected using a SATA to USB adapter. Therefore, there are 7 drives used per 1 node. The reasoning for this is to make better use of ceph’s block device, and also because we had the need to add more disk space.

Network Performance

In addition to the internal ethernet board we are bonding 3 dual port gigabit ethernet PCIe devices. We originally wanted to use a cheap fanless L2 switch, so we use Adaptive Load Balancing instead of link aggregation to distribute traffic.

There are a lot more ethernet cables than there are machines, as you can see from the above picture.

GPU Benchmarks

Since we are in possession of various GPUs that can run tensorflow and chainer, we took benchmarks throughout development. We had a few cards that ran on the Maxwell architecture (GTX 750ti, 970, 980ti) and a majority of the cards that ran on the Pascal architecture (GTX 1050ti, 1060, 1070, 1080). What we found out is that the performance, power efficiency, and cost performance of each card changed depending on the algorithm being used.

Here are some of our findings. This data was collected at varying points in time which unfortunately means we weren’t able to measure performance within the same environments, so it’s a little difficult to draw direct comparisons.

Speed

We measured how many seconds it took to process a given amount of data (the meaning of batch changes per algorithm, so we chose process / sec out of convenience). The results of two algorithms, train.py and char_cnn.py, when run on all available GPUs is shown below. A larger value means more data being processed (better). As expected, the performance increases with more power GPUs. However, there’s an odd case with train.py running much faster on the GTX 980ti.

f:id:rettydev:20170530152833p:plain

In comparison, char_cnn.py actually runs slower on the GTX 980ti. At the time of benchmarking, the GTX 980ti was running in a machine with a cheap AMD CPU. We believe that char_cnn.py is a CPU sensitive algorithm which could explain the large difference. One thing that has me scratching my head is that while train.py seemed to have the best performance on the AMD CPU in general, char_cnn.py did not have any real change in performance using the 750ti. We’re recruiting (日本語) anyone who is interested in digging deeper into this mystery.

Energy Efficiency

Next up we measured energy efficiency. Measured as QPS (process / sec) / W.

f:id:rettydev:20170530152848p:plain

The Pascal architecture in general had pretty good energy efficiency when compared to the Maxwell’s 970, but the GTX 750ti was a very pleasant surprise considering it does not require any additional power.

Cost Performance

This was calculated based on the price of the GPU as of early October 2016 and the energy consumption subtracted from that price. One yen per iteration. Since the prices of the cards change so much, I don’t think this is a very helpful benchmark.

3c49c1b6-017f-94f4-27aa-d112f09b4811.png f:id:rettydev:20170530152901p:plain

Energy consumption was measured using an off-the-shelf power meter.

Other

One thing that I should note is that the energy efficiency of the Pascal architecture has improved. The Maxwell architecture required a lot of energy, but that problem was fixed with Pascal.

As for the cost performance statistic, it all really depends on the timing of when you calculate the numbers because of how quickly the prices of GPUs can drop. For example, the 980ti dropped in price by half after 5 months.

With the way development of GPUs is currently going, products are going to the outlet bin and dropping prices fairly quickly. That’s why we decided it was best buy little by little in order to mitigate potential loss from fluctuating prices. It makes me wonder how SaaS providers who share GPUs deal with that issue.

And lastly, since our server architecture is mostly decided now, I believe it’s time for us to do some proper benchmarking. There’s functionality in place to scale using the cloud, so it’s possible to compare how consumer grade GPUs do against server grade GPUs as well. If that sounds like something that interests you then please subscribe to the Retty Advent Calendar or come check us out (日本語). You don’t have to be a student either, we’re open to everyone.

http://qiita.com/advent-calendar/2016/ranking/subscriptions/categories/company

Personal Database

Data is required for machine learning. Lots of data. At Retty, we have a massive database consisting of millions of user reviews and even more food-related pictures as well as other related information that we are able to use publicly.

To make it as smooth as possible to experiment with, we thought it would be convenient to use that database as a base for a personal database that you can tweak as you see fit. But, due to the massive size of the database, building such a thing is not an easy task. Restoring an AWS RDS database snapshot for use as a personal database ended up taking almost half a day to finish, which isn’t very realistic for real world purposes.

The Retty machine learning infrastructure takes advantage of ceph’s block device snapshot and cloning functionalities. What took up to half a day, now only took 3 seconds4. That’s roughly 12,000 times faster. To put it into a more conventional comparison, that’s fast enough to escape Earth’s gravity. The world sure has changed5.

Snags along the way

There were issues with our servers crashing completely. The biggest two reasons are as follows.

A DoS attack on CIFS

We were using an cheap off-the-shelf NAS to store images when we first built the machine. NAS was not able to handle all of the requests from the machine learning machine, which caused the CIFS file system kernel module to act up and causing all of the machine learning machines to spit out a Linux kernel oops. Since we couldn’t hook up a monitor to the machine it proved difficult to debug, but we were able to investigate it once we installed kdump. The problem was solved by moving on from CIFS and switching to NFS.

Only 1 network segment

Currently, all of our machine learning servers are hooked up to the same 24 port fanless hub. Sometimes there was just so many broadcast packets that the L2 segment became unresponsive (this happened about 2 times in half a year). At this point 2 times doesn’t seem like a huge deal to us, but it’s something we might fix in the future.

Although it’s not exactly a good thing when looked at from a SPOF point-of-view, including the physical network and power to the office, when the server does happen to go down, we all take advantage of the lunch taxi (日本語) or all-expenses-paid meal (日本語) perks to go out and enjoy a nice meal. You could say that the SPOF helps strengthen communication in a ways, so it’s not completely bad.

Retty’s machine learning infrastructure’s development environment

The infrastructure went through many improvements at the beginning while it was it was being made available to others. There was only one person to make use of it at the beginning and worked reasonably well. Eventually the infrastructure grew into a cluster and another person also started using the systems, which proved difficult to make improvements smoothly. For that reason, a development environment for the machine learning infrastructure itself was born.

f:id:rettydev:20170530150841p:plain

This environment uses a virtual machine that can do everything including the automatic OS deployment. It uses VT-d to share the GPU with the specified virtual machines. It’s not possible to use the GPU with just a certain virtual machine which makes this machine restrictive for development that requires GPU usage.

Virtual Machine Creation

We’re using libvirt to handle the management of virtual machines. The biggest plus is that it’s easy to manage virtual machines through the command line, and since it’s made by RedHat it’s able to run well on many Linux distributions.

The virtual machine’s primary disk is running off the machine learning infrastructure’s ceph drive. ceph had problems when installing the virtual machines using the virt-install command, so we added some new code to it.

※ Since virt-install is licensed under GPL, the following patch code is also licensed under GPL

diff -ru /usr/share/virt-manager/virtinst/devicedisk.py /usr/local/share/virt-manager/virtinst/devicedisk.py
--- /usr/share/virt-manager/virtinst/devicedisk.py      2015-11-30 20:47:47.000000000 +0000
+++ /usr/local/share/virt-manager/virtinst/devicedisk.py        2016-11-09 05:12:36.513295726 +0000
@@ -464,6 +464,7 @@
         "source_volume", "source_pool", "source_protocol", "source_name",
         "source_host_name", "source_host_port",
         "source_host_transport", "source_host_socket",
+        "auth_username", "auth_secret_type", "auth_secret_uuid",
         "target", "bus",
     ]
 
@@ -744,6 +745,9 @@
 
     seclabel = XMLChildProperty(Seclabel, relative_xpath="./source")
 
+    auth_username = XMLProperty("./auth/@username")
+    auth_secret_type = XMLProperty("./auth/secret/@type")
+    auth_secret_uuid = XMLProperty("./auth/secret/@uuid")
 
     #################################
     # Validation assistance methods #
@@ -867,6 +871,12 @@
         self._change_backend(None, vol_object, parent_pool)
 
     def set_defaults(self, guest):
+        pool = self._storage_backend.get_parent_pool_xml()
+        if pool.source_auth_type != "":
+            self.auth_username = pool.source_auth_username
+            self.auth_secret_type = pool.source_auth_type
+            self.auth_secret_uuid = pool.source_auth_secret_uuid
+
         if self.is_cdrom():
             self.read_only = True
 
diff -ru /usr/share/virt-manager/virtinst/storage.py /usr/local/share/virt-manager/virtinst/storage.py
--- /usr/share/virt-manager/virtinst/storage.py 2015-12-24 16:30:15.000000000 +0000
+++ /usr/local/share/virt-manager/virtinst/storage.py   2016-11-05 04:29:29.270748502 +0000
@@ -380,7 +380,10 @@
                        "capacity", "allocation", "available",
                        "format", "hosts",
                        "_source_dir", "_source_adapter", "_source_device",
-                       "source_name", "target_path",
+                       "source_name",
+                       "source_auth_type", "source_auth_username",
+                       "source_auth_secret_uuid",
+                       "target_path",
                        "permissions"]
 
 
@@ -406,6 +409,10 @@
                               default_cb=_default_source_name,
                               doc=_("Name of the Volume Group"))
 
+    source_auth_type = XMLProperty("./source/auth/@type")
+    source_auth_username = XMLProperty("./source/auth/@username")
+    source_auth_secret_uuid = XMLProperty("./source/auth/secret/@uuid")
+
     target_path = XMLProperty("./target/path",
                               default_cb=_get_default_target_path)

Using the patch above, it’s possible to specify in the command line arguments a way to allocate the virtual machine’s primary disk on the ceph block device.

virt-install --name=hoge --vcpus=4 --memory=4096 --disk rbd:hoge/fuga ...

Usage as Desktop

This development machine has been turned into a desktop that shows information about the machines. We call it the “Retty Machine Learning Infrastructure Dashboard”. Using the development machine’s GPU, we display the current system information for all of the machines in the infrastructure using a 50 inch 4K monitor.

There’s also an HDMI splitter available that lets engineers have their own view of the dashboard as well.

We thought it would be a waste if that’s all we used it for, though. So the computer has also been turned into a machine that anyone in the office is able to do development directly using the machine or test their own code on it.

This machine has 128GB of memory. It’s also connected directly to all of the machines using a 3Gbps shared bus (3 port ethernet), so it’s acting as if it’s all one machine.

In other words, Retty has a desktop machine with a combined total of 448GB of memory. Since memory is directly related to development capabilities, it’s a good time to be alive. In addition, the 12 GPUs give this desktop machine over 20,000 cores to work with. If this is something you’d like to try out then please check out or post here (日本語).

Summary

Thank you for reading this post.

The Retty machine learning infrastructure has become a desktop machine with 20,000 GPU cores, nearly 500 GB of memory that our engineers can use at any time and scale in the cloud like an amoeba as needed.

I started this project thinking “Just what is a GPU anyway?”. I went through many iterations with the restrictions of buying the cheapest parts available at the local stores, and using open source software and techniques for the software-side of things. The creation of the machine learning infrastructure has lead to the discovery of new server side techniques that can be applied even outside of the infrastructure. Retty also started participating in the open source community.

Having lining up at 5am in my university days at the electronics store to buy a 980 yen VHS player limited to the first customer only, to also successfully living off 800 yen worth of gas a month (日本語), I would like to think that the low cost development has been a great success. (At that price, it’d even be possible to make one server per engineer.)

And at the same time Retty’s earnings have greatly grown which has lead to an increase in the technology budget. Next year we will finally be able to make great progress on the tech side. These benefits will flow back to the engineers, the power behind the technology, further strengthening the investment.

To anyone into machine learning that wants to sink their teeth into a big data-capable desktop machine with 500 GB of memory, and to server-side engineers who would like to innovate with a machine learning infrastructure that can scale like an amoeba using the cloud: following Retty’s vision of “making the world happier, one meal at a time”, we plan to kick new development into full throttle.

Thank you for reading until the very end. Although I got really technical here, I hope this post is a Christmas present for all of the young people out there that aspire to learn machine learning. And I would also be happy if this post made you interested at all in our company. In that case, check this page out next. Thank you very much, and have a good rest of the year.

Bonus

Our PC gamer engineer Yuta building the first machine

Opened

Finished

Everyone disappointed after losing the lottery drawing for the GTX 1080


  1. Since any machine can go down for maintenance and undergo changes, the idea behind this is to say that all of the files are shared between machines, so you should always make sure to create checkpoints and have functionality to restore on any other machine. It might sound like a rough way of doing things, but when done correctly it provides a low cost way to speed up innovation. Please check out the following article: https://cloudplatform.googleblog.com/2015/05/Introducing-Preemptible-VMs-a-new-class-of-compute-available-at-70-off-standard-pricing.html

  2. akiba is what we call the Retty machine learning infrastructure.

  3. For example, a g2.2xlarge spot instance in the AWS Tokyo region is roughly $0.15/h as of 2016/12/20.

  4. Since the kernel module handling ceph block devices does not support snapshots for cloned block devices, we make use of a personal database stored in a VM to do what we want.

  5. Having previously worked at a cloud-native company before joining Retty, the latest techniques in the field of infrastructure technologies felt like a completely different world to me. However, I came to realize that applying various available techniques and tweaking them to perfection lead to a significant impact on operations. So, from now on it’s my goal to try applying the latest techniques whenever possible in the future in an effort to increase operation speed even more.

Retty裏入社式2017を行いました!

みなさん、こんにちは。 新卒エンジニアとして4月から入社しました新卒エンジニアの田松、竹野、Brenton(ブレントン)です。 今回はRettyの伝統行事になりつつある「裏入社式」というものについて紹介します。

f:id:rettydev:20170522164423j:plain

Retty裏入社式とは

裏入社式と聞いてピンと来ない方も多くいらっしゃると思いますが、決して怪しいことをしている訳ではありません(笑) Retty裏入社式とは、2016年の新卒が企画し実行したことが始まりとなった行事で、新卒全員で社員を巻き込む行事を企画、運営し、実際に行っているものとなります。 去年の裏入社式の様子はこちらに記事が挙がっています。

今年はこんな新卒が入ってきたんだよ!と全社を巻き込む最初の機会であり、入社後の新卒同士、他社員との繋がり強化や、伝統作りとして今年も開催させて頂きました。また、入社式で社員さんに祝ってもらった僕たちが今度は社員さんに恩返しという意味も込めて楽しい行事を考えてみました。

今年の裏入社式のテーマ

さて、今年の裏入社式ですが新卒の総合職が企画を考案し、今年の新卒にはエンジニアがいるので、その企画に合わせて僕たちエンジニアがサービスを一つ作らせて頂きました。

今年のテーマは「修学旅行」です。 社会人の僕たちが学生の頃を思い出せるような内容を企画組が考えてくれました。修学旅行と聞くと誰でもワクワクしますよね!

開発したサービスは、人から探すマップです。Rettyの強みである実名制という性質を使って、信頼できるあの人が実際に行ってオススメしているお店を地図上から探すことができるというサービスです。このサービスを社員向けに作成し、使って頂きました。

実際に行った内容

実際に行なった内容ですが、複数チームに別れて社員とのゆかりある店をクイズ形式で出題し、そこに来店を朝昼夜と行い、クイズの正解数に応じて景品がもらえるとういうものです。また、途中のレクリエーションでは花屋敷に伺いみんなで遊び、面白い写真大会を行いました。ここで面白い写真を撮ったチームにポイントを付与し、そこでもポイントを稼げる形を取りました。

そこで、クイズの選択肢としてエンジニアが作ったマップ内のお店、口コミを使い、そのままマップのルートに従って来店しました。

サービス概要

今回のサービスは、現段階ではリリースされるものではないので、アプリ内には実装せずスマホwebを利用しました。 自分が選択した人の行ったお店リストが地図上に表示され、口コミを見ることができます。 アプリ版のRettyの地図表示に似たような画面になっていますが、現在、Rettyでは自分が信頼できる人の行ったお店をリストから閲覧することが出来ますが、それをマップに表示する機能が備わっていませんので、今回はこの課題を新卒エンジニア3人で解決してみました。

f:id:rettydev:20170524144055p:plain

機能要件

サービス中の機能要件は

  • Google Map APIを利用し、複数店舗の店の地図表示機能
  • 作成された上記の地図の複製・編集機能
  • ユーザーIDを入力としたお店の簡易な検索ロジック

の3点になります。

サービスの構成

今回作成したWebアプリケーションは、特段凝ったつくりでなくシンプルです。

フロントエンド側は

バックエンド側は

開発時間も限られていることから、なるべく危険を犯さずシンプルな作りにして分業をしやすくし 各分担の担当者が使い慣れているようなもの、を使った形です。

tornado(Python)を利用したWebサーバ

tornadoは、スケーラブルでノンブロッキングなWebサーバを 簡単に構築するためのライブラリです。

C10K問題の解決に向けて、スレッドの使い回しを行ってくれます。 今回のサービスは社員向けだったため 、やや過剰性能になりますが 使い慣れている技術を使う、ということで採用しました。

以下のようなコードでWebサーバが構築できます

from tornado import ioloop, httpserver, httpclient


class MainHandler(web.RequestHandler):

    def __init__(self, *args, **kwargs):
       super().__init__(*args, **kwargs)
       logger.debug(self.get_template_path())

    # GETリクエスト
    def get(self):
       # do something ...
       self.render("index.html")

    # POSTリクエスト
    def post(self):
       # do something ...
       fuga = {"hoge" : "fuga"}
       self.render("index.html", data=fuga)


def make_app():
    return web.Application([
          (r"/", MainHandler), # {endpoint}/ -> MainHandler に ルーティング
       ],
       template_path=os.path.join(os.getcwd(),  "templates"),
       static_path=os.path.join(os.getcwd(),  "static"),
       debug=True, # ファイルの更新の自動同期機能等が有効となる
    )


def main():
    port = 10000
    app = httpserver.HTTPServer(make_app())
    app.bind(port)
    app.start(1)  # CPU数. 0:全てのCPU 
    ioloop.IOLoop.current().start()

また簡易なテンプレートエンジン*1も備えており、下記のようなテンプレートの使い回しが可能です.

<html>
   <title> {% block title %}裏入社式プロジェクト 2017{% end %} </title>

   {% block ext_block %}
   <p> デフォルトの表示  </p>
   {% end %}
</html>
{% extends "base.html" %}

{% block title %}Viewモード{% end %}

{% block ext_block %}
  <p>Hello world!</p>
{% end %}

MySQLにおける地図のハッシュIDの生成

今回サービスを構築する上で GETリクエストのパラーメータに ハッシュIDごとに地図を表示/編集します.

例えば、以下のようなURLを発行します

https://[endpoint]?id=7ae63asofmkl23iord

今回、重複がないような新しいハッシュ値の発行をMySQLだけで実現しました. やり方としては、新しいレコードをINSERTするときのAFTER トリガーに 以下のようなSQLを発行し これを各種データと関連づけただけになります

INSERT INTO ura2017_map_hash (map_id, hash) 
VALUES (NEW.map_id, MD5(NEW.map_id))

UNIQUE制約を設けておくことで, 重複する場合には新しいINSERTは失敗します.

裏入社式を終えて

今回の裏入社式が新卒メンバーでの初めてのチーム開発となりました。新卒だけでチームを組み、企画から開発までみんなで行うといった経験はなかなかできるものではなく大変貴重な機会でした。この行事を通して新卒同士はもちろん、普段喋れないような社員さんたちとも深く交流することができ、多くのことを学ばせていただくことが出来ました。裏入社式がRettyの伝統となり、来年以降も続いていくと面白いですね!

*1:tornado.templateに具体的な仕様・利用例があります.

RettyとKotlinの歩み〜アプリからサーバサイドまで

RettyでAndroidエンジニアとして働いている福井 と サーバサイドエンジニアの石田です。 本日Googleから「AndroidでKotlin正式サポートする」と発表されました! 🎉🎉 そんなKotlinですが、弊社では去年2月頃からプロダクトに導入しています。今回はその歩みと一年以上使ってきた感想をご紹介します。

Androidでの導入事例

最初にKotlinを導入したのはAndroidチームでした。タイミングとしては1.0が正式リリースされる少し前から導入を検討していました。

まずはプロダクトと直接関係ない小さなアプリを書き、これで行ける!と判断したのと正式リリースのタイミングがちょうど重なり導入を決断しました。1 プロダクトに導入する際は、新規ファイルを作成する時にJavaではなくKotlinで書くといったようにファイル単位でじわじわKotlin化していきました。今ではJava : Kotlin = 2 : 1 くらいの割合まで増えています。

現在Androidアプリをリニューアルする計画があって実際に開発も始まっているのですが、今のところ フルKotlin です。特に大きな縛りもなくJavaかKotlinかどちらで書くのかは各開発者に委ねられているのですが、全員がKotlinを選択したということになります。

Androidでの導入してよかったところ

JavaではなくKotlinを選んだ理由はいくつかあるのですが、実際Androidアプリに導入して特によかったところを簡単に2点挙げていきます。

コレクションが便利

Javaと比較してKotlinはコレクションが充実しています。 例えば、ユーザ情報が格納されたListのうち、課金ユーザのみ取り出したいといった場合はこれだけで書けます。 (弊社のサービスではユーザさんに課金する機能はありません。あくまで一例です。)

val premiumUsers = allUsers.filter { it.isPremium == true }

Delegationが充実している

Javaにはない機能としてDelegationがとても便利です!Lazyなんかも好きですが、Observable も大好きです。これを使うと気軽にreactiveなコードが書けたりします。

例えば何かの状態を表す文言を表示するTextViewを表示する場合、その状態をObservableしておけばいい感じに表示されます✌️ コードはたった3行!

    var status by Delegates.observable("") { _, _, new ->
        statusTextView.text = new
    }

サーバサイドでの導入事例

AndroidチームがKotlinを導入してまもなく、アプリAPI開発チームがKotlinに興味を持ちはじめました。

もともとアプリAPIはJava8で作られた比較的新しいプロダクトで、Optional型やラムダを積極的に使っていたため、当初は導入に消極的でした。

が、チームメンバの1人がおもむろにKotlinでエンドポイントを開発→すんなり動いたことをきっかけに導入に拍車がかかり、新規で作成するファイルや、既存の小さいファイルのリファクタリングを積極的にKotlinで書くようになりました。2 こちらも現在ではJava : Kotlin = 2 : 1 くらいの割合まで増えています。

サーバサイドでKotlinを導入してよかったところ

導入のきっかけはあまり積極的なものとは言えませんが、結果的には導入してよかったと思っています。その中でも特に良かったところを以下に2点挙げたいと思います。

拡張関数が便利

Kotlinには既存のクラスにインスタンスメソッドを追加で生やせる、拡張関数という機能があります。「このクラスにこんなメソッドもあったらいいのに!」と言ったケースに、**Utilsみたいなクラスを生やしたりしなくてよくなります。例えばMapからクエリ文字列を生成する関数を以下のように定義することができます。

fun <K, V> Map<K, V>.toQueryString(): String {
    return this.keys.map { key ->
        this[key]?.let {
            "$key=${URLEncoder.encode(this[key].toString(), Charsets.UTF_8.toString())}"
        }
    }.filterNotNull().joinToString("&")
}

そして、これを定義しておけば、他のインスタンスメソッドと同じように map.toQueryString() とコールすることができます。

データを持つだけのクラスを簡単に記述できる

サーバサイドの場合、他のプロダクトとのやり取りをする上でデータ形式を定義するケースが多いと思いますが、Javaの場合、単にデータを持つだけのクラスを作るだけでもgetter/setterを含めて結構な行数のクラスを書く必要があります。こういったケースのためにKotlinにはデータクラスというものが用意されていて、プロパティを複数個持つだけのクラスをシンプルに記述できます。

data class User(val userId: Int, val userName: String, ...)

KotlinはNULL安全や型推論をはじめとする、モダンな言語の機能を一通り揃えていて、一見目新しい機能はあまり無いように見えますが、エンジニアの直感に沿って、比較的ストレスが少なく書ける言語だと感じます。あと名前がかわいい。

Kotlinを一緒に書いてくれるエンジニア募集中!

Androidはもちろん、いろんなプロダクトでKotlinを書きたいエンジニア募集中です!

また、弊社は毎月Androidもくもく会を開いています。もくもく会とはいっていますが、もくもくするだけだはなく質問タイムを取っているので、「実際にKotlinどうなの?」「こういった場合困らない?」など自由に聞いてもらえます! 弊社に入社したいかはともかく、気軽にKotlin書きたい、使用感を聞いてみたいエンジニアさんはぜひお越しくだだい!

retty.connpass.com


  1. 弊社は各プロダクトで使う言語・フレームワークは各チームの判断に委ねられているのでサクッと導入することができます✌️

  2. 弊社は各プロダクトで使う言語・フレームワークは各チームの判断に委ねられているのでサクッと導入することができます✌️ ※大切なので二回言いました

PyCon mini Kumamoto 参加報告! #PyConKuma

f:id:rettydev:20170425150903j:plain

Retty株式会社に4月から入社しました竹野です。

入社早々になりますが先日の4/24に熊本で開催されました
PyCon mini KumamotoにRettyも参加してきました!

本日はその報告をさせていただきます!

TD;LR

  • PyConだよ。全員あつまれ in 熊本
  • Rettyも参加したよ
  • やっぱりいいよね、Python

PyConとは?

Pythonista(Python使う人)があつまるプログラミング言語コミュニティのことです。 好きなフレームワークPythonを使った開発・分析事例などなど Pythonに対するアツイ思いを語ります!
今回はそんなPyConが熊本にて開催されました、テーマは「未来」です

大盛況で終えたPyCon mini Kumamotoでしたが
今回この場を借りて、その発表の一部をここで紹介させていただきます。

Python お前なによ

キーノートでは Ian Lewisさんより
5年にわたるコミュニティ運営に携われた経験から、Pythonのコミュニティ活動の歴史と これからの課題について整理していただきました。

Pythonがこれだけ活用されるようになったのは
後方互換性を保証することで積みあげられたた長年の信頼の結果」という お言葉を寺田さんからいただいてハッとしました。 プログラミング言語においても大切なのは「人」であることに違いありません

余談ですがPyConJP恒例の 「おまえ、誰よ?」の元祖がイアンさんというのに驚きでした!

まだ見ぬバグゼロという未来

SQUEEZE レガシーコード改善録(スライド)

SQUEEEZE 新井さんよりの社内での取り組みについての発表でした。
Python成分は少なめですが、内容は特濃!

「テストコードがほとんぞ存在しなかった現場」で
「テストを書く習慣を普及させる」までのお話です。

企業のあるあるからに始まり、コードの品質を保証するための文化普及させるまでの勘所や
大事なマインドセット弊社にも取り入れるべきところは皆悪と思います。
数値の見える化がみんなの意識を変えていく、というお話がとても印象的でした。

Python@AWS LambdaとDjangoを使ってアスキーアート自動生成Webアプリを作ってみた

熊本に本社を構える株式会社ワイズリーディングの矢野さんからのご発表!
asciiアートを画像から自動生成するサービスを構築するお話しでした。

画像→ascii文字の系列変換を行うための問題の定式化から
それをWebにのっけるまでのお話は、「おぉー」となるところが多く、聞いていてとてもワクワクしました!

PyCon JP 2017でのご発表も検討されているそうなので、参加される方は必見です!

Rettyからの発表

大盛り上がりのPyCon mini Kumamotoでしたが
弊社の岩永、中川の発表に加え、僕もLTさせていただきました!!

数理モデリングからはじめるPython数理最適化

f:id:rettydev:20170425150906j:plain

弊社の岩永が数理最適化に関する発表を行いました。

発表ではPythonライブラリのPuLPを利用した数理最適化の導入にはじまり
Retty上のデータを活用して「グルメな人で東京のおいしいお店を網羅する」問題を
数理最適化の問題として解きました。

ScrapyとRedashではじめる野球統計学福岡ソフトバンクホークスを添えて

f:id:rettydev:20170425150905j:plain

ScrapyとRedashではじめる野球統計学(スライド)

野球xPythonといえば…中川さん!
今回は得点価値からみた、福岡ソフトバンクホークス北海道日本ハムファイターズの打線の分析について発表を行いました。

Pythonによる自然言語処理 2017 〜spaCyの紹介〜」(LT)

f:id:rettydev:20170425150907j:plain

Pythonによる自然言語処理2017 〜自然言語処理ライブラリ spaCyの紹介〜

Python自然言語処理ライブラリspaCyについて簡単に紹介してきました。
spaCyでは自然言語処理用途に特化したインタフェースを提供してくれます。

せっかくなので簡単に解説させてください パイプラインや系列ラベリングのデコーディング、学習などの自然言語処理用途に特化した インタフェースを提供してくれるライブラリはほとんどないのですが、spaCyはそれを提供してくれます。 そしてIndustrial-Strengthとうたうだけに、これまでのライブラリと比べると速くなっています。

僕のなかでのイチオシは オンライン学習によるモデルの更新も可能になっています。
特に自然言語処理タスクはドメイン依存の傾向が強いため、この更新機能は実応用する 上で嬉しい機能となっています。

PyCon mini Kumamotoを終えて

今回参加して、みなのPythonにこめる想いを肌で直に感じることができました!  

マイコンからWebサービス、ネイティブアプリの構築方法、そして機械学習やデータ分析まで これだけ多くの分野の方々が、一同に会し共有できる場というのは滅多に無いように感じます。 これもひとえにPythonの開発やコミュニティ運営に携わってきた方々の血と涙の結晶によるものです。

運営のみなさま、熊本のみなさまありがとうございました!

f:id:rettydev:20170425150910j:plain

【オマケ】RettyはPyCon JP 2017にプラチナスポンサーとして協賛いたします!

RettyはPyCon mini Kumamoto 2017に引き続き、

日本最大のPythonのお祭りPyCon JP 2017にプラチナスポンサーとして協賛させていただくことになりました!

PyCon JP 2017スポンサー一覧

当日は企業ブースの出展やノベルティーだけでなく、社内のPythonista達がPyCon JPを盛り上げるべく色々と準備をしていますのでお楽しみに!!

RettyではPythonistaなメンバー達と一緒にビックデータ基盤を作りたいエンジニアを募集しています!

Retty流Pythonのススメ

みなさんこんにちは.

お店さん*1商品(FRM*2商品開発)チームでTech Lead(エンジニアリーダー)をしています, nakagawa(@shinyorke)ともうします.JOINしてから3ヶ月たちました.

FRM商品開発チームではエンジニアチームのマネジメントやプロダクト企画・開発を行いつつ,個人としてはPythonが大好きで公私共に良く触って(愛して)います.*3

このエントリーでは,最近のRettyにおけるPythonの利用事例や学び方を紹介したいと思います.

  • Rettyのエンジニアチームの雰囲気を知りたい
  • 機械学習・Deep Learning以外のPythonの使われ方ってあるの?
  • 学ぶ際のオススメが知りたい

上記のどれかに当てはまる皆さま,是非最後までお読みいただけると幸いです.

Retty流Pythonのススメ

「RettyにおけるPython利用状況」「Python学習ノウハウ」「コミュニティ」の3つのテーマで紹介します.

使い方〜RettyにおけるPython利用状況

RettyではプロダクトのコードとしてPHP,Java,Javascript(node.js), Kotlinなど様々な言語・フレームワークが使われています.*4

Pythonもよく使われている言語の一つで,

  • 機械学習自然言語処理など,データサイエンティストなお仕事.いわゆる「PyData*5」と呼ばれる分野.
  • サービスレベルでのデータ運用(ETLなど).データベースやログなどからデータを収集&活用するためのスクリプトやバッチなど.RettyではTreasure Dataとの連携周りで活用しています.
  • 手元の作業(CIやデプロイなど)を楽にするためのスクリプトや便利ツール作成・運用. bashzshで書くのには重いな…というものをPythonで開発など.
  • 管理ツールなど,小規模のWebプロダクト開発. 私の観測範囲内ではWebフレームワークとしてDjango*6がよく使われています.

といった形でプロダクトやツールで目的に合致している箇所で活用しています.

ユーザーさんやお店さんが使うサービス・プロダクトへの適用については,リニューアルのタイミングでPythonでリニューアルする計画があり,徐々にではありますが進めている最中だったりします.

学び方〜RettyにおけるPython学習のノウハウ

主に私の啓蒙活動になります笑.

徐々にPythonistaが増えてきて,Pythonをはじめようかな?覚えようかな?といったエンジニアメンバーもちらほら増えてきており,オススメの学び方や本について聞かれる機会が多くなりました.

そんなメンバーの皆さんが快適かつ素早くPythonを学習できるよう,社内のQiita Teamに学習のためのTipsページを立てています.

ちなみに私は以前Python入門者向けの学習フローを公開しており,こちらで得た知見および過去の実践経験*7を元に,社内のQiita Team内にページを作成・公開しています.

ここですべてを公開できないのが残念ですが,これからPythonを覚えるぞ!という方にポイントを簡単にご紹介します.

Python 3を使うこと

  • Python 2は2020年でサポートが終わる. PEP373に明記されています.
  • PyDataやWebフレームワークもほぼ全てPython 3対応が進んでおり,2を選ぶ理由が限りなく少ない.
  • AWS LambdaやGoogle App EngineなどのPaaS系サービス,インフラ系ツール(aws cli, gcloud)などは一部未対応,ここだけ2を使う.

AWS LambdaはPython3.6に対応がされているとのことです!リリースノート(AWS)

公式のチュートリアルを活用

コミュニティのイベントや勉強会に参加する

その他いくつか細かいポイントがあるのですが,こちらはまた別の機会で紹介できればと思います.

コミュニティ〜参加・登壇の支援とスポンサー

学ぶためには社内の知見のみならず,外のコミュニティを活用して幅広く知見を得ることも重要です.

Rettyではコミュニティ主催のイベント・カンファレンスや勉強会の参加をチケット代・交通費負担などで積極的にサポートしており,DroidKaigi 2017データ分析基盤Nightなど,登壇するメンバーも増えてきています.

Python使いも負けてられない!…ということで,この度4/23(日)に開催される「PyCon mini Kumamoto 2017」にゴールドスポンサーとして協賛させていただくことになりました!

kumamoto.pycon.jp

Rettyからはスポンサードの他,データサイエンティストの岩永が数理最適化について,そして僭越ながら私nakagawa(野球の人)はScrapy*8とRedash*9を用いた野球データ分析についてトークをさせていただきますので,お時間がある方は是非いらしてください!

まとめ

いかがでしたでしょうか?

RettyでのPython活用事例を通じて,学習の仕方やコミュニティ・イベントの参加などのきっかけ作りになってもらえれば幸いです.

最後になりましたが,RettyではPython使いを募集しています!

食やPythonに関するお話はもちろん,PyCon mini Kumamotoの土産話やこのブログに対する意見ツッコミなど,お話をしたくなった方は是非遊びに来てください!

素敵なPythonistaライフを!

*1:レストランや飲食店のこと.Rettyではみなさんへの敬意を大切にする意味でお店さん,と呼んでいます.同様の理由でユーザーはユーザーさんと呼んでいます

*2:Fun Relationship Managementの頭文字でFRMと呼んでいます,いわゆるCRMのC(Customer)の部分をお店さんから見た場合のFun(ユーザーさん)に置き換えたプロダクトとなります.

*3:Pythonコミュニティーでは「野球の人」と呼ばれています.詳しくは「野球 Python」「野球統計学」「セイバーメトリクス」で検索してみてください.

*4:言語やフレームワークの取捨選択は各チームのTech Leadとチームに委ねられているため,様々な環境が存在します.

*5:https://pydata.org/ Pythonを用いたデータに関するあらゆることをオープン化してデータ活用をもっと便利にしよう,という取り組みとコミュニティのこと.日本にもPyData.Tokyoほか,幾つかのコミュニティがあります.

*6:Pythonで最もメジャーなWebフレームワークで,海外ではInstagramをはじめ事例が多数,日本ではチケットキャンプさん,connpass(ビープラウドさん),ビザスクさんなどで使われています.

*7:仕事で触り始めたのが2011年なのでかれこれ6年ちょっとPythonにたずさわっています

*8:Python製のWebクローラ・スクレイピングフレームワーク.サイトの収集からデータ取得まで,DjangoRuby On Railsの用にアプリとして書けるのが特徴 https://scrapy.org/

*9:Pythonベースのデータ分析・基盤ツール.TableauやMackerelと同じような用途で用いられる https://redash.io/