数年前、Lokadを設立してから数年後、私は供給チェーンの最適化に関しては、どんなアプリケーションも素晴らしい結果をもたらすことはないと気づきました。私たちは最善を尽くしましたが、それでは十分ではありませんでした。Lokadの初期バージョンに新機能をどれだけ追加しても、新しいクライアントごとに、これまで対応できたすべてのクライアントとはまったく異なるように思えました。供給チェーンの課題は単に多様すぎて混沌としすぎており、_正気の範囲内_のメニューやボタン、オプションに収めることはできません。

Pythonプログラミング言語とは関係のないヘビの画像。

実際、私たちの多くの競合他社もこの状況を認識し、_正気ではない数_のメニューやボタン、オプションを備えたソフトウェア製品の構築に取り組んできました。これは、_すべての_供給チェーンの課題に対処するための必死の試みとして行われたものです。残念ながら、この道はソフトウェアの怪物を生み出し、壮観な 失敗につながります。私はこの反パターンを非ユークリッドの恐怖と呼んでいます。

したがって、_単一の_アプリケーションでは解決できない問題のクラス、つまり供給チェーンの課題に直面して、私たちは偶然1にも_meta-problem_に取り組むことになりました。つまり、特定の企業のための補充最適化など、各アプリケーションが特定の状況のために1つの問題の解決に専念するような、_ベスポークアプリ_を提供する方法です。

ビジネス向けのベスポークソフトウェアの提供は、新しいことではありません。ソフトウェア業界は60年代にそのように始まり、後に80年代には私たちが今日知っている主流の縮小包装モデルに進化しました。一般的に、ベスポークソフトウェアは、縮小包装と比較して多くの望ましくない特性を持つ傾向があります:前払い投資の増加、長期的なセットアップ、保守コストの増加、リスクの増加など。

しかし、Lokadの最初の数年間の経験から、供給チェーンの最適化に関しては、ベスポークソフトウェアには_1つの_重要な利点がありました:実際に_素晴らしい_結果をもたらすことです。実際、私たちの元のアプリケーションは、予測の正確さに関係なく、最高でも_まずまず_の結果を提供していました2が、これらのプロトタイプは頻繁に_素晴らしい_結果を生み出していました。さらに、関与しているソフトウェアのピースは、手の問題に特化していました。

あらゆる代替手段を使い尽くした後、私たちはベスポークアプリの提供が唯一の方法であると結論づけました。しかし、スケーラビリティ、つまり多くのアプリケーションの提供方法、および_保守性_、つまり保守コストを管理する方法は、2つの中核的な懸念事項でした。 まず、_プログラミング言語_を選択する必要がありました。当時、私たちは多くのオプションを検討しました:R、Python、JavaScript、Lua、C#など、そして後にEnvisionとして知られる私たち自身のドメイン固有のプログラミング言語(DSL)を導入することも検討しました。これらのオプションの長所と短所について議論することはやや退屈であるため3、Python対Envisionの選択に絞って議論を行うことにしました。Pythonは、私たち自身のDSLを導入することに対して最も強力な競合他社でした。

Pythonはそのシンプルさと、特に機械学習分野での豊富なサードパーティエコシステムのおかげで魅力的でした4。また、Pythonとその人気のあるライブラリのほとんどがオープンソースであるため、Lokadにとっては低コストなオプションでした。私たちはPythonの狭いサブセットを再パッケージ化し、数十の厳選されたパッケージをホワイトリストに登録して完了するだけでした。Lokadのほとんどの作業は、供給チェーンの課題に特化したHerokuのようなPaaS体験を提供することに集中することになりました。

しかし、ここで私たちが考慮したのは、1週間に1日働くビジネスアナリスト(後にサプライチェーンサイエンティストとして知られるようになる)が、10億ドルの企業の補充などのミッションクリティカルなサプライチェーンの課題を解決するための本番グレードのアプリを提供できることが合理的であるかどうかということでした。Pythonのオプションを見ると、そのような運用効率のレベルには到底近づくことはできないことが明らかでした。

まず第一に、Pythonにはソフトウェアエンジニアが必要です。実際に、Pythonは完全なプログラミング言語のように、Pythonでコードを書く人に対して多くの技術的な複雑さを露呈します。サプライチェーンサイエンティストの役割は後に形式化されましたが、スマートで才能のある人々を考慮しても、サプライチェーンエンジニアリングの専門家でありながらソフトウェアエンジニアリングの専門家でもあることを期待するのはあまりにも多くのことでした。私たちは、プログラミングの能力を、プロのソフトウェアエンジニアだけでなく、技術的に傾向のある幅広いスペクトルの人々が利用できるようにする必要がありました。

そのため、私たちはEnvisionを作成し、Pythonでは避けられないさまざまな技術的な問題のクラスを排除するための言語としました。例えば:

  • オブジェクトは_null_になることがあり、日付は過去や未来に極端に遠くなることがあり、NaNはデータパイプラインを通じて幸せに伝播することができ、文字列は極端に大きくなることがあります… サプライチェーンでは、これらの「機能」は問題の元です。
  • オブジェクト指向の要素(つまりクラス)は誤用されることが保証されており、同様にカスタム例外や正規表現も同様です。これらの要素の存在自体が、せいぜい不健康な注意散漫さを引き起こします。
  • Excelスプレッドシートを含む異なる形式の表形式ファイルの解析など、複数の基本的な操作は言語の一部ではなく、多くの異なるパッケージを扱う必要があり、それぞれに独自の技術的な複雑さがあります。

これらの技術的な問題のクラスは、Pythonから削除することなく、言語自体を無力化することはできません。Envisionは、_予測的なサプライチェーン最適化の問題_に焦点を絞ったため、プログラミング言語として、サプライチェーンの専門家(ソフトウェアの専門家ではなく)がアクセスできるようになりました。

Excelスプレッドシートで計算を行った経験を思い出し、Excelシートを見ることなく電話で行った変更をすべて口頭で伝えることを想像してください。それが実践者によって推進され、ソフトウェアエンジニア(サプライチェーンの専門家ではない)によって実装されたサプライチェーン最適化の取り組みの姿です。ビジネスは、ITに何を望んでいるのかを理解しようとするために膨大な時間を費やし、ITはビジネスが何を望んでいるのかを理解しようとするために膨大な時間を費やします。Lokadでの10年の経験から、サプライチェーンの専門家ではないソフトウェア開発者に、量的なサプライチェーン最適化の取り組みを提供することは、ソフトウェアチームがどれだけアジャイルで才能があっても、コストを少なくとも5倍に増やすことになります。

次に、急いで作成されたPythonのプロトタイプの保守コストが高騰することについて説明します。ソフトウェア業界以外の多くの人々は、ソフトウェアエンジニアリング5が主に保守コストを管理することに関わることを理解していません。しかし、サプライチェーン最適化の問題を解決することは、混沌としたプロセスです。多くの(不十分な)信頼性のあるシステムからのデータを信頼性のあるパイプラインに送り、不完全で絶えず変化するプロセスを文書化し、モデル化する必要があります。最適化メトリックスは常に変化するビジネス戦略を反映しており、ソフトウェアのどの部分がサプライチェーン最適化を提供するために書かれても、世界が私たちに投げかけるドメイン固有の複雑さが大量に組み込まれます。

しかし、時間は重要です。昨年の生産計画のための完璧な計画を持っていても意味がありません。おおよその目安として、ソフトウェアのプロトタイプが動作し始めた日から数週間以内に本番環境に移動されることが確実です。プロトタイプがうまく書かれているかどうかに関係なくです。

上層部がプロトタイプをメンテナンスの観点から本番グレードに書き直すために6ヶ月の遅れを承認することを期待するのは甘い考えです。しかし、急いで作成されたPythonのプロトタイプを本番環境に導入すると、メンテナンスのオーバーヘッドが発生し、24時間365日のダクトテープで修正しなければならない大量のバグとの戦いになります。

したがって、本番環境を正常に保つ唯一の実用的な方法は、プロトタイプを_設計による正確性_を保証するプログラミング言語で書くことです。例えば、Pythonとは異なり、Envisionは次のような機能を提供します:

  • コンパイル時に保証された_有限の実行時間_:膨大なデータを処理する際に、計算が終了しないことに何時間も待つのは非常に退屈です。
  • コンパイル時に保証された境界付きメモリ消費:夜間の本番バッチでメモリ不足のエラーに苦しむことは楽しいものではなく、実際には業務を混乱させます。
  • アトミックな読み書き:Envisionは、ファイルがFTPを介してプッシュされる間にスクリプトが実行されている場合でも、ファイルシステム内での同時読み書きを設計上防止します。Envisionのバックエンドのファイルシステムは、巨大なフラットファイルに合わせてカスタマイズされたGitのようなものです。適切な_データ_のバージョン管理がないと、多くのバグはハイゼンバグに変わります。問題に深入りする時点で、データが更新されているため、問題を再現することができなくなります。
  • 環境におけるスケールアウト:データが数十ギガバイトを超えると、並列化の障害は避けられなくなりますが、Envisionは計算リソースのクラウド上でプログラムを実行することで、そのすべてを解決します。

汎用のプログラミング言語は、設計による正確性をほとんど提供しません。Pythonは遅延バインディングのスペクトルに寄りすぎており、この領域では非常に少ないです。Rustなどのより良い代替案を考慮しても、サプライチェーン最適化にとっては満足のいくものではありません。

以下は、Pythonでは簡単には実現できないEnvisionの優れた点のいくつかです:

防御の深さ:組織内で誰かがコードを書き始めるとすぐに、6特別な注意が払われない限り、そのコードはITセキュリティの観点から即座に負債になります。Pythonを介して、Pythonスクリプトを実行しているマシン上で_何でも_可能です。Pythonを適切にサンドボックス化することは、実際には非常に複雑な問題です。特に、Pythonスクリプトによって生成される任意の文字列は、潜在的なインジェクションベクトルです。SQLインジェクションは悪名高いですが、CSVなどのプレーンテキストファイルでもインジェクション攻撃の脆弱性があります。EnvisionはPythonでは実現できないレベルのセキュリティを提供します。データ漏洩が増加しており、Pythonの断片があちこちに散らばっていることはITセキュリティにとって何の利益にもなりません。

透明なパフォーマンス:プログラムの実行が非現実的に遅い場合、そのプログラムは最初からコンパイルされるべきではありません7。プログラムが1行短くなった場合、プログラムの実行速度も速くなるべきです。1行だけ変更された場合、同じデータでプログラムを再実行する際には、その1行だけが再計算されるべきです8。コンパイル時には、コンパイラは特定のマシンではなく、計算リソースのクラウドをターゲットにするべきであり、自動的なデータ駆動型の並列化を提供するべきです。Envisionは、これらの特性をデフォルトで提供するため、コーディングの努力を必要としません。一方、Pythonでは、このような特性を近似するために、専門のライブラリを大量に使用する必要があります。

透明なアップグレード:ソフトウェアに関しては、最新の状態は常に移り変わるものです9。2010年には、最高の機械学習ツールキットはSciPy(おそらく)でした。2013年にはscikit、2016年にはTensorflow、2017年にはKeras、2019年にはPyTorchが最高でした。ソフトウェアエンジニアリングでは、ソフトウェアプロジェクトの誕生年を、そのソフトウェアスタックと依存関係を見ることで判断できると言われています。実際、独自のPythonスクリプトを展開すると、うまくいかない可能性のある複数の依存関係が発生します。一方、Envisionでは、自動的なコードの書き換えを活用して、「レガシー」スクリプトを常に最新の言語に合わせて更新しています。

パッケージ化されたスタック:Pythonスクリプトは単体では使用できません10。コードはバージョン管理(例:Git)とアクセス権(例:GitHub)が必要です。実行するための環境が必要です(例:クラウド上のLinux VM)。データパイプラインをオーケストレートするためのスケジューラが必要です(例:AirFlow)。データの準備には分散型の列指向ストレージレイヤーが必要です(例:Spark)。予測分析には機械学習ツールキットが必要です(例:TensorFlow)。サプライチェーンの組み合わせ問題に対処するために最適化ツールキットが必要です(例:GLPK)。生の結果は後で使用するためにどこかで公開する必要があります(例:SFTPサーバー)。サプライチェーンの専門家は進行中の状況を監視できる必要があります(例:Webユーザーインターフェース)。アクセス権限を強制する必要があります(例:Active Directory)など。Envisionは、これらすべてを1つのメタアプリに統合し、最も基本的なアプリケーションでも数十のソフトウェアを組み立てる手間を省きます。

そして、優れた言語である一方で、Pythonには批判の余地があります:

  • 計算パフォーマンスが悪く、データ処理タスクで極めて悪いパフォーマンスを避けるために、すべての計算を_適切な_ライブラリ(例:NumPy)を介して行う必要があります。さらに、複数のライブラリを使用すると、データを次のライブラリに移動する際に多くの摩擦が生じる傾向があります。
  • メモリパフォーマンスも悪く、特にPythonの参照カウントガベージコレクションは_時代遅れ_です。最新のプログラミング言語(Java、C#、JavaScriptなど)はトレースを使用しています。メモリ集約型のタスクやビッグデータの処理においては、これは問題です。
  • Pythonのパッケージ管理は長い間 混乱していましたし、パッケージの専門家が正しく行うために必要でした。また、高い摩擦のある言語のアップグレードにより、この問題はさらに複雑化しました。
  • (ほとんどの)正当性チェックは実行時にのみ行われ、データ処理に関わる場合には無限のフラストレーションの原因となります。明らかな問題は、数分の実行後にのみ明らかになり、生産性が低下します。

結論として、Pythonは素晴らしい言語ですが(本当にそうです)、サプライチェーンの最適化には満足のいく答えではありません。Pythonで本番レベルの機械学習アプリを構築・維持することは十分に可能ですが、コストはかなりかかります。また、少なくとも少数のソフトウェアエンジニアリングチームがこのアプリのメンテナンスに専念する準備ができていない限り、サプライチェーンに満足のいく結果をもたらすことはありません。

予測的なサプライチェーン最適化に特化したドメイン固有のプログラミング言語であるEnvisionを開発することは、私たちの最初の選択肢ではありませんでした。それは私たちが従来の代替手段の長いリストを使い果たした後に、唯一の動作する解決策であるというよりも、むしろそうでした。7年後、多くのクライアント企業を経ても、新しいクライアントはいつも何らかの形で私たちを驚かせ続けています。それは、クラシックなエンタープライズウェアのアプローチでは決して受け入れられなかったサプライチェーンのさまざまな変化です。プログラム可能性が必要でしたが、Pythonは私たちが必要とする解決策ではありませんでした。


  1. 2013年当時、私はサプライチェーン最適化の満足のいくアプリを提供することが可能だという印象を持っていました。実際には、価格設定の課題との対決が私たちを追い込み、Lokadを独自のドメイン固有言語の構築の道に導きました。この言語は最初は価格最適化のためだけに意図されていましたが、すぐにサプライチェーン最適化にも必要なものであることがわかりました。 ↩︎

  2. 単に優れた予測精度を提供することが、優れたサプライチェーンのパフォーマンスにつながるという考えは、Lokadを創設する際に私が抱いていた最大の誤解の1つでした。この問題については、Lokad TVのエピソードでより理性的な視点をご覧ください。 ↩︎

  3. Pythonに関連する問題のほとんどは、Pythonそのものとは関係ありません。Pythonは素晴らしいプログラミング言語ですが、単に_汎用的_なプログラミング言語であるというだけです。 ↩︎

  4. 2013年当時、Pythonはまだ機械学習分野で獲得した支配力には至っておらず、Rはまだ強力な競合相手でした。ただし、優れたライブラリであるSciPyとNumPyは既に存在しており、当時から活気づいていました。 ↩︎

  5. ソフトウェアエンジニアリングは、_コンピュータサイエンス_とは異なります。前者は生産システムの確保に関するものであり、後者はより高速なアルゴリズムの発見など、困難な問題の解決に関するものです。 ↩︎

  6. 残念ながら、コードのセキュリティに関しては、コードの体系的なピアレビューに代わるものはほとんどありません。 ↩︎

  7. 停止問題により、注意深い読者はEnvisionがTuring完全言語ではないことを推測するかもしれません。実際、Envisionはそうではありません。 ↩︎

  8. Envisionは計算グラフの差分に依存し、大規模なデータセット上で非常に高速なプロトタイピングを可能にするために、増分変更の間の再計算量を最小限に抑えようとします。ただし、状況によっては、1行の変更でもスクリプト全体の再計算が必要になる場合があります。 ↩︎

  9. ジェネリックなプログラミング言語に対して自動化されたコードの書き換えは非常に困難です。プログラミング言語とその標準ライブラリ全体がこの要件を念頭に置いて厳密に設計されていない限り、自動アップグレードツールは実際にはほとんど役に立ちません。Envisionを設計する際、私たちは多くのことを間違えることを知っていました(そして実際に間違えました)、そのため、言語が自動化された書き換えに特に適していることを確認するために非常に注意を払いました。Envisionの創設以来、100以上の増分的な書き換えを行っています。 ↩︎

  10. 皮肉なことに、「電池が付属しています」はPythonのモットーの1つです。ただし、予測的なサプライチェーン最適化のためのアプリを構築するために必要なすべての要素を結びつけるために必要な接着剤の量は非常に多いです。 ↩︎