はてなキーワード: コンパイラとは
セキュリティソフトウェアの研究開発、という仕事を自分の経験をもとに紹介します。主な想定読者は、情報セキュリティ関連を仕事にしたいと考えている学生や若手、特に、いわゆる「低レイヤー技術」に惹かれている人です。
低レイヤ技術を間接的に仕事で生かしてきた経験の共有。元Linuxカーネル開発技術者の場合 - 覚書を読んで思い出したのですが、セキュリティキャンプなどで、セキュリティに興味のある学生とやり取りをしていて、ソフトウェアエンジニアリングの分野でセキュリティ関連のキャリアが議論されることが少ないと感じました。自分はセキュリティソフトウェアの研究開発に10年以上携わっていることもあり、この職業は低レイヤー技術をセキュリティに活かせる面白い選択肢だと思っているので、紹介してみることにしました。
セキュリティソフトウェアの研究開発では、アンチウイルスやEDRなど、文字通りセキュリティ機能を提供するソフトウェアを研究、開発します。
「研究、開発」と書いたように、この職業には研究と開発の両面があります。
研究は、実現可能性や価値が定かでないアイディアを調査、試験実装する、という仕事がその一部です。例えば、ファイルをディスクに書き込まないマルウェアを検知したいが、どのような技術的選択肢と課題があるかを評価する。実現可能な場合は、開発チームと協働して実装、出荷にこぎつける。あるいは、製品として実装された機能がバイパスされないか調査したり、バイパスされてしまった場合にはその原因を究明したりして、製品を改善するために開発チームと協働する、という場合もあります。
開発は、研究との対比という意味においては、できると判っているアイディアを保守性の高い状態で実現する作業だといえます。保守性の重視は研究との大きな違いで、例えば、研究では、コメントもテストものない書き殴りのコードで十分であっても、開発の工程では、5年後でも改修が必要になるため許容できなかったりします。製品という大きなコードの中での開発であるため、別のチームや利害関係者との連携も、研究の場合よりずっと重要です。例えば、リードのポジションであれば、研究工程で実現可能と分かったアイディアが、既存の機能に統合する形で実装されるべきか否かアーキテクトと議論したり、テスト計画を品質保証のチームと練ったり、プロジェクトのスケジュールを調整したりします。
研究は、既定の手法がなく、闇の中を手探りで進める面があり、最終的に製品レベルにこぎつけずに終わる場合も多いです。判りやすい成果が出ない場合があるので、好き嫌いが別れやすいです。自分は、職業としては研究3,開発7くらいのバランスが好きで、趣味では逆に研究8,開発2くらいになってます。趣味では成果が出ようが出まいが過程が楽しければ満足、という個人的な考え方がこの違いとして出ているようです。
この職業のおいて、低レイヤー技術に明るいことは、ほかの多くのエンジニアができないことができるという付加価値、だと自分は考えています。例えば、特定分野の詳細を知っていることでその分野の研究、開発が効率よくできたり、新しいアイディアが生まれたりします。具体例をいくつか挙げると、OSの仮想メモリー管理に親しみがあれば、プロセスのメモリーを走査してメモリー上のみに存在するマルウェアを検出する機能をより効果的に設計、実装できる。プロセッサーの機能の詳細を知っていれば、CETという新しいプロセッサーにしかないセキュリティ機能を、他のプロセッサー機能を使って疑似的に実現するというアイディアを思いつく。などです。脆弱性の知識や探す技術も、とても価値があります。脆弱性を知らない人と、知っている人では、どちらが脆弱性の少ない設計や実装をできるでしょう。自社の製品の脆弱性を、開発中に発見するのと、テスト・出荷後に発見、改修を加えるのではどちらのコストが少なくて済むでしょう。コンパイラーの知識は検出ロジックを書くための独自言語の開発に、エミュレーターの実装経験はマルウェア解析エンジンの開発に役立ちます。
ただ、低レイヤー技術は付加価値であることに注意してほしいです。
まず前提として、ほかの平均的なエンジニアができることに加えて低レイヤー技術があるべきです。セキュリティソフトウェア開発者の多くは、実はセキュリティや低レイヤーのエキスパートではありません。優秀な開発者であることに加えてこれらを必要条件にしてしまうと、人が雇えなくなってしまうためです。そのため、一般的なエンジニアリングの能力に加えて低レイヤー技術やセキュリティという強みがあると、大多数の開発者ができない(したがらない)ことを任せられる人、と差別化してもらえる可能性が高いです。一方、エンジニアリングに対する素養や意欲なしでは、セキュリティソフトウェアの研究開発職は難しいです。その場合、研究者のほうがあっています。(ちなみに自分は、脆弱性解析とマルウェア解析を専門とする研究職にも各2年ほど就いていました。)
ここからは一般論になりますが、OSに詳しくても、プロセッサーに詳しくても、バグハントが得意でも、それを会社が求める結果を出すために使えなくては意味がありません。会社は、あなたがやりたい仕事をくれません。会社は、会社が必要としている仕事をもってくるだけです。
ではどうやって「会社が必要とする仕事」と「あなたがやりたい仕事」の重複を最大化するか。
まずは、上司にどういう仕事をしたいかを明示的に、繰り返し話しておきます。さらに、能動的に、自分からプロジェクトのアイディアを提案して意欲を示すことも心がけます。あなたの仕事を最終的に選ぶのは上司である以上、上司からの理解は必須です。良い上司(そして良い上司であることを可能する、良い上司の上司)は、必ず、あなたの能力に対する信頼度に応じて、あなたの意向を考慮してくれます。言い換えると、まずはやりたい仕事を主張する前に、与えられた仕事をこなして信頼を得る必要があります。個人的な経験では、これは1年あれば十分で、1年たっても状況に変化がない場合、あなたの仕事ぶりが上司の信頼を得るのに不十分か、あなたがやりたい仕事をうまく伝えられていないか、上司やその上司あるいは会社に問題があるか、あるいはこれらの組み合わせの可能性が高いです。
上記がうまくいかない場合、チームや会社を変えることを検討しましょう。チーム異動はリスクの少ない選択肢です。これも、実現するか否かは、上司からの信頼の程度に大きく依存します。会社を変えるのはリスクが大きいですが、上司やその上司を変えるよりも現実的です。新しい会社でもうまくいかなかったら、また新しい会社を探せばOKです。最終的にあった会社に行きつくか、自分の能力やコミュニケーションに問題があることに気づくと思います。
最後に、「会社が必要とする仕事」と「あなたがやりたい仕事」の重複を追求しないことも視野にいれておきましょう。仕事はあくまでお金のためであって、やりたい仕事のほうが楽しいが必要要件ではない。……という視点を持っておくと、些細なミスマッチで不満をためて、そこそこ良い環境から性急に転職してしまう、という状況を防ぎやすいです。隣の芝生は青い、ということを忘れないように。
セキュリティソフトウェアの研究開発は、セキュリティに深く関わりつつ低レイヤー技術を付加価値として自分を差別化できる面白い職業です。
ところで自分は7年務めた研究開発職を退職しました。おめでとう、ありがとう。これからは、また違う低レイヤー技術+セキュリティの研究開発をしていきます。
素人で調べたところだと、
こんな感じで普通の人が知るのは難しそうだ。
お絵描きやプログラミングなど、創作系の趣味において、自分が欲しいものがなかったり、あっても不満だったりすると、「自分で作ってしまおう」というのは一番ありがちな動機
自分で作ろうと思った時に選択するツールがアナログ画材なのか、液タブなのか、AIなのかの違いなんてその時点での目的の達成しやすさの違いでしか無いじゃん?
曲作りたいなら打ち込みかもしれないけれど、モテたいが目的なら自分でギターを弾くじゃん?
手作業の温かみなんて求めてハンドアセンブルで手動最適化なんてせず、コンパイラの自動最適化のほうがよっぽど高度に最適化してくれるじゃん?
基本情報・応用情報試験みたいなのとか、CPUの仕組み、コンパイラの実装、分散システムやデータベースとかそういうエンジニアリングガチ勢みたいなのをイメージして大学でCSを学ぶとけっこうショックを受けるぞ。
俺の知ってるCSは、チューリングマシンの表現能力とか停止性問題とかYコンビネーターとかチャーチ数とかの世界で、コンパイラといってもε-CLOSUREみたいな話をじっくりやる感じ。
具体的な話が全然出てこない数学の一ジャンルってイメージかもな。
競技プログラミングみたいなアルゴリズムもそれほど時間をかけない。ベイズ推定をギリやるかどうか。
そういう知ればすぐ身につくものよりも、めちゃくちゃ考えて濃厚なパラダイムを時間をかけて吸収するような学問だった。
で、そんなCSを学んで直接役に立つのは多くの人の場合計算量のオーダーとかくらいかも。
モナドみたいな概念に抵抗なくなるとか、ラムダ式の意味を深く理解できるというのもあるけど、それSIとかWebやスマホアプリの開発業務で必要かというとね。
賢い人は、ちゃんとSNSのユーザー同士の関係性とかレコメンデーションみたいのにもCSの知識を応用できると思うけど、一般人は賢い人が作ったライブラリを使う側だよね。
構文解析は勉強したことないとまずわからないよね。でも趣味でやる人たちもいるくらいだから、ひと通り学べばどうってことはないんだけど。(コンパイラを作るとかなら話は別だけど)
無粋なツッコミをしとくと
この辺はいわゆるコンピュータサイエンスの範疇じゃないよね。特に4つ目。
コンパイラを作るための理論とかはコンピュータサイエンスの範疇と言っていいだろうけど
申し訳ないが、コンピュータサイエンスを履修せずにプログラマーになった人に多いのは
まずそもそも困っていることに気付けていないのでスタートラインに立ててない
スラムダンクでいうところの「下手くその 上級者への道のりは 己が下手さを知りて一歩目」というやつだ
ちなみにコンピュータサイエンスってのはオーダの話だけではなくて
例えばメモリとCPUキャッシュ、スワップなどのスピードやその使い方、コンパイラによる最適化、OSのリソース共有、状態管理の考え方なんかも含まれる
性能をもっと上げたいっていうときにオーダだけじゃなくてそういうことを網羅的に考える必要がある
ところがそもそもコンピュータサイエンスを履修してないと「性能向上が必要かどうか」を分かって無い人が多い
「これ、1秒で処理終わってるけど、本来なら1msec以内に終わるはずじゃない?」
というのに気付けてない場合が多い
1秒で処理が終わればユーザ体験は満足してしまうので気付けないんだが、ユーザが増えてくるとユーザ体験が途端に悪くなってくる
そのときに「プログラミング上のミスがあって性能が劣化している」ということに気付くか、「性能限界だからさらなるリソースが必要」と誤解するかによってビジネス上の戦略まで変わってくる
それだけではなくてクリーンアーキテクチャみたいな話も「機能が増えたんだから実装に時間がかかってバグが増えるのは当たり前」というところに落とし込んでしまうか
「もっとアーキテクチャを整理して考えれば機能追加も楽になるはず」という考えに至るか、というところで大きな差がある
この辺りでビジネス上の戦略まで変わってしまうからGoogleやMicrosoftなんかは積極的にコンピュータサイエンスを履修してる人を雇う
もう少し簡単に言うと、コンピュータサイエンスを履修してないプログラマーに多いのが
「今は動いているけれど触るとどうなるかわからない」
というソフトウェアを作りがちなところだと思う
レビューしてても
というコメントをするが、大抵
「動いているのでいいでしょwww」
みたいな感じで返してくるからどうしようもない
Danbooruの素性に注目が集まっているが、ここでは議論しない。
promptを英語で書く必要があり、闇雲に入力しても意図した画像が出てこない。
promptチェッカーのような、正しいpromptが書けているのかどうかをコンパイラで確認できず、自身で画像を見て反映されているか判断する必要がある。
promptに記載した内容が1枚の画像に全て反映されているわけではなく、複数枚の画像を出力してみて、promptがなんとなく反映されているかな、といったものになる。
Danbooruのタグが使えるということが正しいように広まっているが、半分正解で半分間違っている。
「bow」というタグがあるが弓を表しているわけではなく、女の子キャラクターの髪の毛が弓なりの形状をしていることを示すのに、Danbooruではタグ付けされている(ように見える)。
「hair_bow」というタグもあり、こちらも髪留めリボンのことを示す。「Waifu Diffusion」に書いて出てくるのはこちらになる。一般的に使われるのもこちらだろう。
面倒なのがここからなのだが、「Waifu Diffusion」は修飾子がどこにかかっているのか曖昧な判断をする。
弓を描きたいわけではないので、何かしら髪にまつわる単語が「bow」の近くにあることになるが、「Waifu Diffusion」はリボンを描く。
どうも「Waifu Diffusion」は英文法を知っているわけではなさそうだ。
また「hair_bow」をつけたキャラクターの代表的なのが東方の霊夢なのか、霊夢要素がそこかしこに現れる。
もう一つ例を出そう。
Danbooruのタグに「small_breasts」という胸の小さいタグがあるが、「Waifu Diffusion」は胸の大きな描写をする。
「xxxx, small_breasts, xxxx」といったようなpromptを書くと、胸の小さいキャラを描きたいのだなと判断すると思うが、
「Waifu Diffusion」は胸という単語があるから胸を描画した、となる。
どうもアンダースコアでつながっている単語を1単語とは認識してない。
「breasts」という単語が入っている限り、巨乳が描かれ、さらに胸をさらけ出した描画がなされるので重々注意されたし。
小さい胸のキャラクターを描きたい場合は「breasts」という単語をpromptに入れてはいけない。
上記のこともあり、Danbooruタグはあまり効かない。!!!やカッコ( ) で括った単語は強調されるらしいが、あまり意味がない。
またDanbooruのタグの詳細を見てみるとわかるが、1kを超えるような数の多いタグは曖昧なものが多くなり、詳細な分類がなされたものは数が少なくて効かない。
「floating_hair」というイラストでよくある髪束をウネウネさせるタグがあるが、「Waifu Diffusion」は認識せず、キャラクターは空を飛ぶ。
「short_hair_with_long_locks」という、ショートだが頬の横の髪が長いというタグがあるが、まず認識されない。
では日本人女性が現実でしている髪型に対応する英語があるかというと、Googleで検索して出てくるような和製英語を入力しても描画されない。
アイドル系だとツインテールがメジャーだと思うが、英語圏の人は「twintail hair は pigtail hair」だというが、pigtail hairは日本人の感覚からすると編み込みが多くリボンが沢山付き、どうも違うとなる。
他に、現状「Waifu Diffusion」では指を描くのがかなり苦手だ。
promptを工夫すれば出来るのかもしれないが、色々試した結果、顔との両立が出来ない。
先の事例と同様に、手を隠すといったpromptは指定しようとしても、promptに指や手といった単語が入っているだけで問答無用で画面に出てくる。
「Stable Diffusion」では本当に効くかどうかはさておき、検索できるサイトがいくつか出てきている。
しかし「Waifu Diffusion」で、アニメを描きたい場合の参考はない。
「Waifu Diffusion」を作った人達のDiscordにtext-to-imageがあり、画像とpromptが載っているが、多くがクオリティの低いものであり、高速で流れるチャット欄から見つけるのは困難だ。
Danbooruデータベースで学習しているということで、実際にダウンロードして中を見てみたが、
玉石混交というか、説明がしにくいが、少なくとも自分の描きたいものとは違っていた。
テイストが揃ってないので、同じ単語が示す物でも画像ごとに違い、そりゃアーティスト名で絞りたくなるよなってのは気持ちはわかる。
(「Waifu Diffusion」でDanbooruのアーティスト名を入れても、狙ったテイストにはならないが。絵が多いアーティスト名でもならない。)
また「Waifu Diffusion」はキャラクターの顔については崩れないので凄いと言われるが、
実際に使うと、「full body」といった全身を描きたいと思っても顔のアップばかりが出力され、全身が描けたと思っても顔が崩れて描写されない。
アニメのような演出をしようと思った場合、エフェクトをどう指定するか、という問題にぶち当たる。
アニメならではの光の演出があるわけだが、どう指定するのかわからない。
最近のイラストで多い、逆光で顔の前面は薄い影で、なぜか鼻の高い所にはハイライトが入っているが、前髪の影は額に落ちているという、
どこから光が入っているんだ?というのも指定できるのだろうか?
まだ3Dでやっているような顔前面セル塗りの方が指定しやすかろう。
「Waifu Diffusion」には70ワードという制限があり、細かく指定していくと軽く超えていく。
超えた分は無視され、絵を文字で表現するとなるのは難しいのを実感する。
img2imgによって、ポーズの指定、髪の毛をどこで括るかといった指定はしやすくなるが、それでもpromptが必要となる。
Danbooruタグが反映されない問題が解決されたとしても、タグの細分化はされているようでいて、実際使うとなると足りてない。
使いこなせる人はいるのだろうか?