による写真 ディープマインド on Unsplash
行列の乗算は、ニューラル ネットワークから科学計算ルーチンまで、多くのシステムで使用される基本的な演算です。 行列乗算の効率的で証明可能な正しいアルゴリズムを見つけることは、計算の高速化と効率化に大きな影響を与える可能性がありますが、非常に困難な作業です。 可能なアルゴリズムのスペースは膨大であり、人間が設計したヒューリスティックや組み合わせ検索など、アルゴリズムを発見するための従来の方法は、多くの場合最適ではありません。
ディープマインドが最近提案した、自動検索のための AI ベースのソリューションは、人間の直感をはるかに超えています。このソリューションは、AlphaTensor と呼ばれる深層強化学習エージェントで構成されており、 アルファゼロ. このエージェントは、TensorGame というシングルプレイヤー ゲームをプレイするようにトレーニングされています。このゲームの目標は、計算効率の高い行列乗算アルゴリズムを発見することです。
AlphaTensor は、大きな行列の乗算を小さな乗算に分解することにより、大きな行列の処理に特に優れています。 さらに、AlphaTensor を使用して、特定のハードウェア デバイスで微調整すると、行列乗算の最先端のパフォーマンスを実現できます。
AlphaTensor は、ディープ ラーニング コンピューティングを高速化する大きな可能性を秘めています。 深層学習では、時間のかかる多くの操作を行列の乗算にマッピングできます。 AlphaTensor を使用してこれらの操作を最適化することにより、ディープ ラーニング モデルの全体的なパフォーマンスを大幅に向上させることができます。
最近、OpenAlphaTensor、 AlphaTensor の最初のオープン ソース実装がリリースされました。これは、ディープ ラーニング モデルの計算能力に革命をもたらす可能性があります。
行列乗算テンソル
行列乗算の最適化の専門家ではない場合、行列乗算などの演算を XNUMX 次元テンソルにマッピングする方法を理解するのは簡単ではないかもしれません。 簡単な言葉と例で説明しようと思います。
簡単にするために、A と B の両方がサイズ N の正方行列である積 C = A*B を考えてみましょう。乗算演算は、形状 (N^3、N^2、N^2) の 2D テンソルにマッピングできます。 最初のテンソル次元は平坦化された行列 A を表し、XNUMX 番目の次元は平坦化された行列 B を表し、XNUMX 番目の次元は平坦化された行列 C を表します。
テンソルは、各エントリに対してバイナリ値 (1 または 0) のみを持ちます。 テンソルは乗算演算を表すため、行列 A および B の値とは無関係であることに注意してください。
テンソルのすべてのエントリは、操作の係数に対応します。 たとえば、C[1,1] を計算するには、A[1,1] と B[1,1] の両方を乗算する必要があります。 したがって、A[0,0,0]、B[1,1]、および C[1,1] に対応するテンソル エントリ [1,1] の値は 1 になります。 ,1,1]、A[2,1] は必要ありません。 したがって、テンソル行 T[N+1, :, 0] にはゼロのみが含まれます。
以下の画像は、N=2 のテンソルの例を示しています。
DeepMind からの画像 紙 に発表され 自然
上の図の (b) と (c) に示すように、3D テンソルの分解を使用して積を計算するアルゴリズムを実装することができます。 より具体的には、以下のアルゴリズムを使用して、テンソル分解 (行列 U、V、W) を行列乗算アルゴリズムに変換できます。
DeepMind で導入された行列積 C=AB を計算するためにパラメータ化されたメタアルゴリズム 紙
テンソルゲーム
行列乗算の効率的なアルゴリズムを見つけるという問題は、考慮すべき可能なアルゴリズムの数が、行列乗算の小さなインスタンスであっても、宇宙の原子の数よりもはるかに多いため、非常に困難です。
DeepMind はこの問題をシングルプレイヤー ゲームに変換し、それを TensorGame と呼びました。 このゲームでは、プレイヤーは行列のさまざまなエントリを組み合わせて乗算する方法を選択します。 スコアは、正しい乗算結果を得るために必要な操作の数に基づいて割り当てられます。 ゼロテンソルに到達するか、最大数の移動が行われると、ゲームは終了します。 最終的な因数分解は、残差ランクの推定と、漸近的な時間の複雑さや実際の実行時間などの特定の最適化基準に基づいて評価されます。
TensorGame の初期位置は、ランダムに表現された行列乗算テンソルに対応します。
ゲームの各ステップ t で、プレーヤーは XNUMX つのベクトルを書き留めます。
、ランク 1 テンソルを指定します . ゲームの状態は、プレーヤーが選択したベクトルを減算することによって更新されます。
コラボレー
行列乗算テンソルです。ゲームが p ステップで終了する場合、これは行列乗算テンソル
p ランク 1 テンソルに分解できます 、つまり、少なくともランク p を持っています。TensorGame はランク分解アルゴリズムとして解釈でき、AlphaTensor はテンソルのランクを推定するためのアルゴリズムと見なすことができます。
AlphaTensor アーキテクチャ
これまで、TensorGame について学び、その解が行列乗算アルゴリズムとしてどのように見えるかを明確にしました。 それでは、ゲームに使用されるアルゴリズムである AlphaTensor の主な概念を調べてみましょう。
AlphaTensor アーキテクチャは、基本的にエンコーダ/デコーダ Transformer アーキテクチャです。
- エンコーダーはゲームの状態を入力として受け取ります 、モデルによって実行された n 回前のアクション (通常は n=7)、および現在のアクションの時間インデックス t。 情報は形状 (n+1, N^2, N^2, N^2) のテンソルにまとめられます。 次に、このテンソルは (2 つの線形レイヤーを使用して) 形状 (N^2、N^XNUMX、c) のテンソルに再形成および変換されます。ここで、c はモデルの内側の次元です。
- デコーダーは、エンコーダーによって与えられた埋め込みベクトルから自己回帰の方法で n_steps アクションを生成します。 各アクションはトリプレットのトークンに対応します ゲーム テンソルを分解する (つまりランクを下げる) トリプレットの XNUMX つを表す
モデルは、逆伝播とモデル動作を交互に行うことによってトレーニングされます。 モデルの演技は、モデルのトレーニングに使用されるデータを生成するために使用されます。 実際には、モデルは、合成的に生成されたデータと、演技中にモデルによって生成されたデータの混合でトレーニングされます。 演技ステップは、行列演算に対応する 3D テンソルを取得し、それに対して n_actors ゲームをプレイすることによって行われます。 各アクターは、標準ベースまたは代替ベースのいずれかでゲームをプレイします (ベースの変更は所定の確率で適用されます)。 その後、結果が収集され、合成データを使用したトレーニング ステップで使用できます。
動作ステップは、AlphaZero のモンテカルロ ツリー検索 (MCTS) に基づいており、大規模なアクション スペースをサポートするように修正されています。つまり、アクションを選択する前に、n_sims パスがモデル出力から探索され、将来の最大探索は 5 ステップになります。モデルによって生成された確率は、生成されたパスを考慮して調整されます。次に、最も有望な将来のパスを持つアクションが選択され、ゲームが続行されます。
モデルのトレーニング中の報酬は、実際には負の報酬 (ペナルティ) です。 その絶対値は、ゲームを解決するために必要な追加のステップごとに増加します。 モデルが TensorGame を解くのに m ステップかかる場合、ゲームに関連付けられた報酬は r=-m です。 モデルが TensorGame を max_rank ステップで解決できない場合、報酬は残りのテンソルのランクを推定することによって計算されます。 ランクは、テンソルを構成する行列のランクの合計として推定されます。 推定値は、テンソルの真のランクの上限です。
モデルを微調整する場合、最終状態でのペナルティ報酬は、モデルによって生成されるアルゴリズムのレイテンシも考慮する必要があります。報酬の式は rt'=rt+λbt になります。ここで、rt は前述の報酬スキーム、bt はベンチマーク報酬 (最終状態でのみ非ゼロ)、および λ ユーザー指定の係数です。
DeepMind の論文から抽出した、GPU および TPU 向けに調整された AlphaTensor が発見したアルゴリズムの高速化 (%)。 高速化は、同じハードウェアでの標準 (GPU の cuBLAS など) 行列乗算と比較して測定され、 Strassen-square アルゴリズム。 ソース: ディープマインド.
最近リリースしました OpenAlphaTensor、AlphaTensor の最初のオープン ソース実装です。 このセクションでは、実装について説明します。 前に説明したように、AlphaTensor アーキテクチャはかなり単純で、エンコーダ/デコーダ アーキテクチャを備えた標準の変換器に基づいています。 AlphaTensor の最も興味深いコンポーネントは、エンコーダー部分の最初のレイヤーと、アクションがサンプリングされる方法です。
最初のエンコーディング層から始めましょう。
# x.size = (N, T, S, S, S)
# scalars.size = (N, s)
batch_size = x.shape[0]
S = x.shape[-1]
T = x.shape[1]
x1 = x.permute(0, 2, 3, 4, 1).reshape(batch_size, S, S, S * T)
x2 = x.permute(0, 4, 2, 3, 1).reshape(batch_size, S, S, S * T)
x3 = x.permute(0, 3, 4, 2, 1).reshape(batch_size, S, S, S * T)
input_list = [x1, x2, x3]
for i in range(3): temp = self.linears_1[i](scalars).reshape(batch_size, S, S, 1) input_list[i] = torch.cat([input_list[i], temp], dim=-1) input_list[i] = self.linears_2[i](input_list[i])
x1, x2, x3 = input_list
上記のスニペットでは、入力テンソルがどのように XNUMX つのテンソルに分解され、変換レイヤーのクエリ、キー、および値の入力として使用されるかを示しています。
- 平坦化された行列 (A、B、C) を表す 1 つのテンソル次元にわたって、入力テンソルは、前のアクションを表す次元と共に各次元に沿って平坦化されます。 このように、入力テンソルの各フラット化されたコピーでは、選択された次元は、選択された次元のすべての S 値について、最後の T-2 値と実際の値の集約です。ここで、S=N^XNUMX です。 哲学的には、各次元について、その次元での以前の行動で何が起こったかに焦点を当てているかのようです。
- スカラーは次元 S^2 の 2 つの異なる空間にマッピングされ、前のポイントで取得されたテンソルと連結されるように再形成されます。 概念的には、スカラーは次元 S^XNUMX の埋め込み空間にマッピングされ、埋め込まれた情報は S ベクトルにチャンクされ、一緒にスタックされます。これは、トークン化されたときにテキストに起こることと同様です。
- スカラー トークンは、再構築された入力テンソルと連結され、モデルの内部次元でスカラー + チャネル履歴フォーカス情報をマッピングするための線形レイヤーへの入力として与えられます。
これらの XNUMX つのステップは、スカラーに関する情報 (TensorGame タイム ステップなど) と、各チャネルの前のアクションへのフォーカスの両方をモデルに与える方法として解釈できます。
アクションが生成される方法に関して、AlphaTensor が、テンソル ランクを下げることを目的としたトリプレット u、v、w を出力として生成することに注目することは興味深いことです。 3 つのベクトルのサイズは S で、連結されているため、モデルはサイズ 3*S のベクトルを生成する必要があります。 AlphaTensor は RL アルゴリズムを使用してトレーニングされるため、すべての可能なアクションは、列挙された空間内の確率で表現する必要があります。つまり、モデルはさまざまなアクションの確率を生成します。 これは、3S 空間の各ベクトルを異なるアクションにマッピングする必要があることを意味します。 これにより、サイズ |F|^(2S) のアクション空間が得られます。ここで |F| u、v、w の要素が取り得る異なる値の数です。 通常、値は (-1、-0、1、2、5) に制限されるため、カーディナリティは XNUMX 要素になります。
ここに大きな課題があります: サイズ 5 の行列の行列積のアクション確率を生成するには、5^75 * 4 バイトのメモリが必要であり、これは ~10^44 GB のメモリを意味します。 明らかに、これほど大きな行動空間を管理することはできません。
問題をどのように解決しますか? アクション確率のメモリ フットプリントを削減するために、トリプレットを小さなチャンクに分割し、それらを「トークン化」し、チャンクをトランスフォーマー アーキテクチャで生成されたトークンとして扱うことができます。つまり、トークンは自動回帰でデコーダーへの入力として与えられます道。 上記の例では、トリプレットを 15 個のチャンクに分割して、メモリ消費を 15 * 5^(75/15) * 4、つまり 187.5 KB に減らすことができます。
def _eval_forward(self, e: torch.Tensor): bs = e.shape[0] future_g = ( torch.zeros((bs, self.n_samples, self.n_steps)).long().to(e.device) ) ps = torch.ones((bs, self.n_samples)).to(e.device) e = e.unsqueeze(1).repeat(1, self.n_samples, 1, 1) future_g = future_g.view(-1, self.n_steps) ps = ps.view(-1) e = e.view(-1, e.shape[-2], e.shape[-1]) for i in range(self.n_steps): o_s, z_s = self.core(future_g[:, : i + 1], e) future_g[:, i], p_i = sample_from_logits(o_s[:, i]) ps *= p_i future_g = future_g.view(bs, self.n_samples, self.n_steps) ps = ps.view(bs, self.n_samples) return ( future_g, ps, z_s[:, 0].view(bs, self.n_samples, *z_s.shape[2:]).mean(1), )
上に、完全なアクションを生成するためのコード スニペットを示します。 コードでは、self.core にデコーダー レイヤーが含まれ、テンソル e はエンコーダー レイヤーの出力を表します。 ゼロはNLP モデルのトークンと、n_steps チャンクを表す n_steps アクションは、漸進的な方法で生成されます。
モデルは XNUMX つの量を返します。
- 生成されたアクション
- フルアクションに関連付けられた確率
- モデル値の計算に使用される最初のアクション (最初のチャンク) を生成するために生成されたロジット。
n_samples パラメータについて少し説明する価値があります。 このパラメーターは演技ステップに使用され、モデルがさまざまなバージョンのトリプレットを生成できるようにします。これは、演技プロセスで使用されるモンテカルロ木探索アルゴリズムでアクション空間を探索するために使用されます。 モデルによって生成されたポリシーに従って、n_samples 個のさまざまなアクションがサンプリングされます。
演技ステップ
アルゴリズム全体で最もトリッキーな部分は、おそらく TensorGame を解くために使用される Acting ステップです。 このアルゴリズムは、AlphaTensor の論文では深く説明されていません。なぜなら、それは、引用され、既知のものとして与えられたいくつかの DeepMind の以前の論文に基づいているからです。 ここでは、不足しているすべての部分を再構築し、実装について順を追って説明します。
演技のステップは、次の XNUMX つの異なるコンポーネントで構成できます。
- モンテカルロ木探索
- ゲームシミュレーション
- 改善された政策計算
それらをXNUMXつずつ分析してみましょう。
モンテカルロ木探索 (MCTS)
モンテカルロ木探索 (MCTS) は、ゲーム、特にボード ゲームやビデオ ゲームで広く使用されている人工知能技術です。 このアルゴリズムは、潜在的な動きと結果をシミュレートするゲーム ツリーを作成し、ランダム サンプリングを使用して、各動きに対して期待される報酬を評価します。 次に、アルゴリズムは、期待される報酬が最も高い動きを繰り返し選択し、最終状態または指定された停止条件に達するまで結果をシミュレートします。 シミュレーションは、各動きの勝率を推定し、意思決定プロセスをガイドするために使用されます。 MCTS は、可能性のある動きと結果の数が多い複雑なゲームで効果的であることが示されており、AlphaGo などの成功したゲームプレイ AI システムで使用されています。
AlphaTensor では、元の MCTS の修正版が使用されます。 特に、アクション スペース全体からアクションをランダムに選択する代わりに、モデルによって直接生成されたサブセットの中からアクションが選択されます (前に示した n_samples を介して)。 ポリシーのアップグレードに対する修正は、改善されたポリシーの計算ステップで適用されます。
私たちの実装では、モンテカルロ ツリーに関するすべての情報を、TensorGame 状態のハッシュ バージョンをキーとして、状態自体に関連付けられた情報を値として持つディクショナリに保持することにしました。 モンテカルロの各ステップはノードから始まり、n_sim ミニゲームをシミュレートし、5 つの動きの地平線で未来を探索します。 ノードが以前のシミュレーションですでに探索されている場合、n_sim は以前の探索の数を考慮して調整されます。 各ノードの訪問数は N_s_a テンソルに格納されます。このテンソルにはノードの子アクションごとの訪問数が含まれているためです (モデルによってサンプリングされたものの中で)。
def monte_carlo_tree_search( model: torch.nn.Module, state: torch.Tensor, n_sim: int, t_time: int, n_steps: int, game_tree: Dict, state_dict: Dict,
): """Runs the monte carlo tree search algorithm. Args: model (torch.nn.Module): The model to use for the simulation. state (torch.Tensor): The initial state. n_sim (int): The number of simulations to run. t_time (int): The current time step. n_steps (int): The maximum number of steps to simulate. game_tree (Dict): The game tree. state_dict (Dict): The dictionary containing the states. """ state_hash = to_hash(extract_present_state(state)) if state_hash in state_dict: with torch.no_grad(): N_s_a = state_dict[state_hash][3] n_sim -= int(N_s_a.sum()) n_sim = max(n_sim, 0) for _ in range(n_sim): simulate_game(model, state, t_time, n_steps, game_tree, state_dict) # return next state possible_states_dict, _, repetitions, N_s_a, q_values, _ = state_dict[ state_hash ] possible_states = _recompose_possible_states(possible_states_dict) next_state_idx = select_future_state( possible_states, q_values, N_s_a, repetitions, return_idx=True ) next_state = possible_states[next_state_idx] return next_state
上記のコードは、アルゴリズムの実装を示しています。 コードを簡単にするために、ポリシーの修正は、simulate_game 関数で実行されます。
ゲームシミュレーション
Simulate_game 関数は、TensorGame の特定の状態を表すノードで構成されるツリーを探索する役割を果たします。 また、リーフ ノードが検出されるたびにモデルを実行し、すべてのノード情報を state_dict ディクショナリに保存します。 その実装を詳しく見てみましょう。
@torch.no_grad()
def simulate_game( model, state: torch.Tensor, t_time: int, max_steps: int, game_tree: Dict, states_dict: Dict, horizon: int = 5,
): """Simulates a game from a given state. Args: model: The model to use for the simulation. state (torch.Tensor): The initial state. t_time (int): The current time step. max_steps (int): The maximum number of steps to simulate. game_tree (Dict): The game tree. states_dict (Dict): The states dictionary. horizon (int): The horizon to use for the simulation. """ idx = t_time max_steps = min(max_steps, t_time + horizon) state_hash = to_hash(extract_present_state(state)) trajectory = [] # selection while state_hash in game_tree: ( possible_states_dict, old_idx_to_new_idx, repetition_map, N_s_a, q_values, actions, ) = states_dict[state_hash] possible_states = _recompose_possible_states(possible_states_dict) state_idx = select_future_state( possible_states, q_values, N_s_a, repetition_map, return_idx=True ) trajectory.append((state_hash, state_idx)) # state_hash, action_idx future_state = extract_present_state(possible_states[state_idx]) state = possible_states[state_idx] state_hash = to_hash(future_state) idx += 1 # expansion if idx = max_steps: trajectory.append((state_hash, None)) if not game_is_finished(extract_present_state(state)): state = state.to(model.device) scalars = get_scalars(state, idx).to(state.device) actions, probs, q_values = model(state, scalars) ( possible_states, cloned_idx_to_idx, repetitions, not_dupl_indexes, ) = extract_children_states_from_actions( state, actions, ) not_dupl_actions = actions[:, not_dupl_indexes].to("cpu") not_dupl_q_values = torch.zeros(not_dupl_actions.shape[:-1]).to( "cpu" ) N_s_a = torch.zeros_like(not_dupl_q_values).to("cpu") present_state = extract_present_state(state) states_dict[to_hash(present_state)] = ( _reduce_memory_consumption_before_storing(possible_states), cloned_idx_to_idx, repetitions, N_s_a, not_dupl_q_values, not_dupl_actions, ) game_tree[to_hash(present_state)] = [ to_hash(extract_present_state(fut_state)) for fut_state in possible_states ] leaf_q_value = q_values else: leaf_q_value = -int(torch.linalg.matrix_rank(state).sum()) # backup backward_pass(trajectory, states_dict, leaf_q_value=leaf_q_value)
各シミュレーションは、次の XNUMX つの部分に分かれています。
- 選択
- 拡張
- バックアップ
選択部分では、既に生成されたツリー ノードでシミュレーションが実行され、次の関数を使用して次のノードが選択されます。
def select_future_state( possible_states: List[torch.Tensor], q_values: torch.Tensor, N_s_a: torch.Tensor, repetitions: Dict[int, list], c_1: float = 1.25, c_2: float = 19652, return_idx: bool = False,
) -> torch.Tensor: """Select the future state maximizing the upper confidence bound."""
# q_values (1, K, 1) pi = torch.tensor( [ len(repetitions[i]) for i in range(len(possible_states)) if i in repetitions ] ).to(q_values.device) ucb = q_values.reshape(-1) + pi * torch.sqrt( torch.sum(N_s_a) / (1 + N_s_a) ) * (c_1 + torch.log((torch.sum(N_s_a) + c_2 + 1) / c_2)) if return_idx: return ucb.argmax() return possible_states[ucb.argmax()]
実際には、ucb 関数を最大化するアクション:
指定された状態が選択されています。 ここで、Q はモデルによって生成された Q 値を表し、π はモデル ポリシーを使用してサンプリングされたアクションのランダム分布を表します。 N(s, a) は、ノード s からアクション a へのノードの訪問回数を表します。
選択フェーズがリーフ ノードに到達すると、シミュレーションが最終条件 (最大探索、つまり将来の地平線、またはゲーム終了のいずれかに関して) に達していない場合、モデルは n_samples の代替ノードを選択するために使用されます (それらはリーフ ノードになります)。連続する反復のノード)。 新しいノードがツリーに追加されるため、これは展開フェーズと呼ばれます。 その後、現在のシミュレーションでそれ以上のノードは探索されませんが、リーフ q_value は次のシミュレーション ステップに送信されます: バックアップ。
バックアップは、各シミュレーションの最終段階です。 バックアップ中に、リーフ ノードが最終状態であった場合、最終的な報酬が計算されます。 それ以外の場合は、葉の q 値が推定報酬として使用されます。 次に、シミュレーションの軌道上で報酬が逆伝播され、状態 q_values と訪問カウンター N(s, a) の両方が更新されます。 以下のスニペットでは、報酬の逆伝播のコードを示しています。
def backward_pass(trajectory, states_dict, leaf_q_value: torch.Tensor): """Backward pass of the montecarlo algorithm"""
reward = 0 for idx, (state, action_idx) in enumerate(reversed(trajectory)): if action_idx is None: # leaf node reward += leaf_q_value else: ( _, old_idx_to_new_idx, _, N_s_a, q_values, _, ) = states_dict[state] if isinstance(reward, torch.Tensor): reward = reward.to(q_values.device) action_idx = int(action_idx) if action_idx in old_idx_to_new_idx: not_dupl_index = old_idx_to_new_idx[int(action_idx)] else: not_dupl_index = action_idx reward -= 1 q_values[:, not_dupl_index] = ( N_s_a[:, not_dupl_index] * q_values[:, not_dupl_index] + reward ) / (N_s_a[:, not_dupl_index] + 1) N_s_a[:, not_dupl_index] += 1
ポリシー計算の改善
すべてのシミュレーションが実行され、MCTS が近い将来の興味深いスナップショットを提供したら、予測されたノードに関連付けられたポリシーを更新してそれらを返し、トレーニング中に使用できるようにします。 で説明されている方法に従って、改善されたポリシー ヒューバートら、大規模なアクション スペースを管理するために使用されます。 実際、探索空間が小さい場合、MCTS 中に行動空間から行動をランダムにサンプリングし、その影響を評価することが可能です。 はるかに大きな行動空間での同様のアプローチは、すべての軌跡が異なる経路で発散することにつながり、意味のある統計を取得してポリシーを更新するには、無限の軌跡が必要になります。 ここでは分散を回避するために sample-MCTS を使用しているため、つまり、モデル ポリシーに従って n_samples アクションがサンプリングされ、MCTS はツリーの探索中にサンプリングされたアクションの XNUMX つを選択するだけなので、計算時にサンプル補正を考慮する必要があります。モデルのトレーニング中に使用される最終的に更新されたポリシー。
実際には、改善されたポリシーは次のように計算されます。
コラボレー
def compute_improved_policy( state_dict: Dict, states: List[str], model_n_steps: int, model_n_logits: int, N_bar: int,
): """Compute the improved policy given the state_dict, the list of states. The improved policy is computed as (N_s_a / N_s_a.sum())^(1/tau) where tau is (log(N_s_a.sum()) / log(N_bar)) if N_s_a.sum() > N_bar else 1. """ policies = torch.zeros(len(states), model_n_steps, model_n_logits) N_bar = torch.tensor(N_bar) for idx, state in enumerate(states): N_s_a = state_dict[state][3] actions = state_dict[state][5] if N_s_a.sum() > N_bar: tau = (torch.log(N_s_a.sum()) / torch.log(N_bar)).item() else: tau = 1 N_s_a = N_s_a ** (1 / tau) improved_policy = N_s_a / N_s_a.sum() for sample_id in range(actions.shape[1]): action_ids = actions[0, sample_id] for step_id, action_id in enumerate(action_ids): policies[idx, step_id, action_id] += improved_policy[ 0, sample_id ] return policies
私たちの実装では、N_s_a テンソルからポリシーを計算した後、それを元のアクション テンソルにマップし直さなければならないことに注意してください。 実際、N_s_a はモデルによってサンプリングされたアクションのみを考慮しますが、最終的なポリシーには、調査されていないアクションの確率も含まれている必要があります。
ChatGPT トレーニング アルゴリズムに関する相違点
AlphaTensor は、DeepMind による人工知能手法の AlphaGo/AlphaZero ファミリーの最新メンバーです。これらの手法は、モンテカルロ ツリー検索 (MCTS) アルゴリズムに基づいており、ますます複雑なタスクに取り組むために DeepMind によって改良および強化されています。もう 1 つの AI システムである OpenAI の ChatGPT は、その驚くべきパフォーマンスで多くの話題を呼びましたが、ヒューマン フィードバックによる強化学習 (RLHF) と呼ばれる別のアプローチでトレーニングされました。
RLHF は、一連の記述された指示に従うように言語モデルを調整するために使用される微調整手法です。 人間の好みを報酬シグナルとして使用してモデルを微調整し、それによって言語モデルの動作を、「人間の価値」のより広い概念ではなく、特定のグループの人々の表明された好みに合わせます。
対照的に、MCTS は、ゲームで最適な動きを決定するために使用されるツリーベースの検索アルゴリズムです。 潜在的な動きをシミュレートし、その結果に基づいて各動きの値を更新し、最良の動きの選択を導きます。
RLHF は、人間が作成したデモンストレーションと人間がラベル付けした AI モデル間の比較からデータを収集し、報酬モデルをトレーニングして、特定のグループの人々の好みを予測します。 次に、報酬モデルを使用して AI モデルを微調整します。 一方、MCTS は、シミュレーションと評価を使用して最良の決定を下します。
アプローチは異なりますが、RLHF と MCTS には類似点もあります。 どちらの人工知能技術も意思決定と問題解決の方法を使用し、試行錯誤のアプローチを使用してさまざまなオプションを探索し、利用可能な情報に基づいて意思決定を行います。 どちらも、より多くの情報と経験が収集されるにつれて、時間の経過とともに改善される反復プロセスでもあります。
RLHF と MCTS のどちらを選択するかは、当面のタスクによって異なります。 RLHF は、モデルのパフォーマンスを評価するための明確なメトリックがない場合に理想的ですが、MCTS は、将来の知識と探索がモデルに大きな利点をもたらすゲームのようなタスクで効果的であることが証明されています。
AlphaTensor トレーニングのコード最適化
AlphaTensor トレーニング アルゴリズムを実装するには、トレーニング速度とメモリ消費の間の完璧な妥協点を見つける必要があります。 モデル セクションで見たように、単純にアクションのトークン化を考慮するだけで大量のメモリを節約できますが、過度に積極的なアクション スペースの削減は、精度の低下とパフォーマンスの低下の両方につながる可能性があります。 後者は、すべてのトークンがモデル デコーダーによって自己回帰的に順次生成されるために発生します。 したがって、アクション スペースのソフトマックスがボトルネックでなくなると、推論時間はアクションあたりのトークン数に比例して増加します。
AlphaTensor トレーニングをセットアップするとき、主な問題は演技プロセスの処理にあることがわかりました。 テンソルが正しい形式で保存されていない場合、MCTS によって制御不能なメモリ使用量が簡単に増加する可能性があります。 一方、各シミュレーション中に保存されるテンソルの数が減りすぎると、MCTS は必要な状態を再計算するために無限の時間を費やす可能性があります。
ゲーム シミュレーション ステップの例を見てみましょう。ここでは、将来の可能性のあるシナリオを検討してゲームを調査します。状態ごとに、モデルによって生成されたアクションを保存せず、ポリシーからアクションをサンプリングするために使用されるランダム シードのみを保存することにした場合、ツリー ノードを探索するたびにポリシーを再計算し、次にアクションをサンプルします。明らかに、私たちは時間を節約し、MCTS 探索の並列化の場合に異なるプロセス間でのモデル共有を管理する必要を避けるために、サンプリングされたアクションを保存することにしました。ただし、アクションを保存するだけでは、十分に効率的なアクション ステップを実行するには十分ではありませんでした。実際、n_steps アクションを (u, v, w) トリプレットに変換し、ゲーム テンソル状態を削減し、n_samples アクションから new3D テンソルを作成する時間は、トレーニング全体のボトルネックになりやすいです。次に、アルゴリズムが使用するメモリに多大な影響を与えるため、サンプルされたアクションごとに考えられるすべての将来の状態を保存することは望ましくありませんでした。 n_samples=32、n=7、N=5 と設定するとします。N は削減したい正方行列積のサイズ、n はモデルによって記憶されている以前のアクションの数であることを思い出してください。この状況では、各状態テンソルの形式は (8, 25, 25, 25) となり、これに 32 を掛けると 32 になります。8252525グラフ内のノードごとに 4 バイト。 ここで、拡張フェーズの各シミュレーションが新しいノードを生成することを考慮すると (n_sim=200)、最終的なメモリ消費量は 200 になります。3282525最初の MCTS ノードだけで 25*4 = 3.2GB。 最悪のシナリオでは、動作中の max_rank ノード (ここで max_rank=150) を探索している間、RAM メモリ (またはすべてのテンソルが GPU に格納されている場合は GPU メモリ) で 150 * 3.2GB = 480GB の合計メモリ消費が発生します。 . 128 GB の RAM と 48 GB の GPU メモリを備えたワークステーションでトレーニングを実行したため、メモリの消費を減らす必要がありました。
実行時間を長くしたくなかったので、生成された状態テンソルの冗長性を利用する最適化を採用しました。実際、テンソルには共通の以前のアクションが n-1 個あり、これらのアクションは一度保存すればよく、保存されたテンソルごとに繰り返す必要はありません。これにより、メモリが 2/7 ~ 28% 削減され、最悪の場合でも 137GB を保存できることになります。この時点で、ツリーの未使用部分 (選択されていない軌道など) を単純に削除し、テンソルを CPU メモリに保存するだけで、トレーニング中のメモリ エラーを回避することができました。
OpenAlphaTensor がオープン ソースになったことで、さらなる開発のためのいくつかのエキサイティングな道が開かれました。
自然な進行は、ターゲット ハードウェア デバイスでの OpenAlphaTensor の微調整です。 これにより、非常に競争力のある計算パフォーマンスが得られると予想されます。 さまざまなハードウェアでの OpenAlphaTensor のパフォーマンスについて詳しく公開します。 GitHubの. この記事を書いている時点で、OpenAlphaTensor はトレーニングを受けていました。
もう XNUMX つの重要な進歩は、リモート コンパイルのサポートです。これにより、ユーザーはエッジ デバイス用に最適化されたアルゴリズムを構築できます。 これは、OpenAlphaTensor モデルをサーバーに保存することで実現できますが、行列乗算アルゴリズムは別のハードウェアで評価されます。
レイテンシーベースの報酬補正を計算するために、さまざまなコンパイラーのサポートを拡張することも重要です。 コンパイラが異なれば、特定のハードウェアで最適化されたアルゴリズムも異なる可能性があります。 たとえば、DeepMind の論文では、TPU と Nvidia GPU で JAX と XLA コンパイラを使用した有望な結果が示されました。 Nvidia の NCCL または CPU の LLVM を使用してこれを評価することは興味深いでしょう。
最後に、より大きな行列サイズをサポートするためにモデルとトレーニング アルゴリズムを拡張することは、未解決の大きな課題です。 現在、OpenAlphaTensor は最大行列サイズ 5 をサポートしていますが、より大きな行列乗算を 5 より小さいサイズの小さな MM のグループに分割することで適用できます。完全な MM は、理論的にはより良い結果につながる可能性があります。
ディエゴ・フィオリ Nebuly AI の CTO です。Nebuly AI は、AI の最適化をすべての開発者のツールキットの一部にすることに取り組んでいます。
- SEO を活用したコンテンツと PR 配信。 今日増幅されます。
- Platoblockchain。 Web3メタバースインテリジェンス。 知識の増幅。 こちらからアクセスしてください。
- 情報源: https://www.kdnuggets.com/2023/03/first-open-source-implementation-deepmind-alphatensor.html?utm_source=rss&utm_medium=rss&utm_campaign=first-open-source-implementation-of-deepminds-alphatensor
- :は
- ][p
- $UP
- 1
- 3d
- 8
- a
- できる
- 私たちについて
- 上記の.
- 絶対の
- 加速している
- 従った
- それに応じて
- 精度
- 達成する
- 達成
- Action
- 行動
- 実際に
- 追加されました
- NEW
- 調整
- 採択
- 進める
- 利点
- 後
- エージェント
- 凝集
- 積極的な
- AI
- AIシステム
- 目指して
- アルゴリズム
- アルゴリズム
- すべて
- 許可
- ことができます
- 一人で
- 既に
- 代替案
- 間で
- 量
- 分析します
- &
- 別の
- 適用された
- アプローチ
- アプローチ
- 建築
- です
- 記事
- 人工の
- 人工知能
- AS
- 割り当てられた
- 関連する
- At
- 自動化
- 利用できます
- 回避
- バック
- バックアップ
- ベース
- 基本的に
- 基礎
- BE
- なぜなら
- になる
- さ
- 以下
- ベンチマーク
- BEST
- より良いです
- の間に
- 越えて
- ボード
- ボードゲーム
- 結合した
- より広い
- BT
- ビルド
- 内蔵
- by
- 呼ばれます
- 缶
- 場合
- 原因となる
- 生じました
- 一定
- 挑戦する
- 挑戦
- 変化する
- チャネル
- AI言語モデルを活用してコードのデバッグからデータの異常検出まで、
- 子
- 選択
- 選択する
- 選ばれた
- 引用された
- クリア
- はっきりと
- コード
- 集める
- 組み合わせる
- コミットした
- コマンドと
- 会社
- 比べ
- 競争力のある
- 複雑な
- 複雑さ
- コンポーネント
- 構成
- 妥協
- 計算
- 計算能力
- 計算
- コンピューティング
- コンセプト
- 概念的に
- 条件
- 信頼
- 検討
- 見なさ
- 考えると
- 考慮する
- 消費
- 含まれています
- 続ける
- コントラスト
- 変換
- 基本
- 対応する
- 対応する
- 可能性
- カウンター
- CPU
- 作成します。
- 作成
- 基準
- CTO
- 電流プローブ
- 現在
- データ
- 取引
- 決めます
- 決定しました
- 決定
- 意思決定
- 決定
- 深いです
- 深い学習
- ディープマインド
- 依存
- 記載された
- 決定する
- Developer
- 開発
- デバイス
- Devices
- DICT
- 異なります
- 困難
- 次元
- 大きさ
- 直接に
- 発見する
- 発見する
- 議論する
- ディストリビューション
- 分割された
- ダウン
- Drop
- 間に
- e
- 各
- 前
- 簡単に
- エッジ(Edge)
- 効果的な
- 効率的な
- どちら
- 素子
- 要素は
- 埋め込まれた
- 終了
- 強化された
- 巨大な
- 十分な
- エントリ
- エラー
- 推定
- 推定
- エーテル(ETH)
- 評価する
- 評価
- 評価します
- 評価
- さらに
- あらゆる
- 例
- 例
- エキサイティング
- 実行
- 拡大
- 予想される
- 体験
- 説明する
- 説明
- エクスプロイト
- 探査
- 探る
- 調査済み
- 探る
- 表現
- 伸ばす
- 延伸
- 非常に
- かなり
- 家族
- 速いです
- フィードバック
- 少数の
- フィギュア
- ファイナル
- 発見
- 名
- フロート
- フォーカス
- フォロー中
- フットプリント
- フォーム
- 形式でアーカイブしたプロジェクトを保存します.
- 式
- 発見
- から
- フル
- function
- 基本的な
- さらに
- さらなる開発
- 未来
- ゲーム
- Games
- 生成する
- 生成された
- 生成
- 生成
- 取得する
- 受け
- 与える
- 与えられた
- 与え
- 目標
- ゴエス
- 良い
- GPU
- GPU
- グラフ
- 素晴らしい
- グループ
- グループの
- 育ちます
- 成長性
- ガイド
- ハンド
- ハンドリング
- が起こった
- 起こります
- Hardware
- ハードウェアデバイス
- ハードウェアデバイス
- 持ってる
- 持って
- こちら
- 最高
- 地平線
- 認定条件
- How To
- しかしながら
- HTTPS
- 巨大な
- 人間
- i
- 私は
- 理想
- IDX
- 画像
- 影響
- 実装する
- 実装
- 重要
- 改善します
- 改善されました
- in
- 増える
- 増加
- ますます
- 独立しました
- index
- 情報
- 初期
- を取得する必要がある者
- 説明書
- インテリジェンス
- 興味深い
- 内部
- 導入
- 直感
- IT
- 繰り返し
- ITS
- 自体
- JPG
- KDナゲット
- キープ
- キー
- 知識
- 既知の
- 言語
- 大
- より大きい
- 姓
- レイテンシ
- 最新の
- 層
- 層
- つながる
- 学んだ
- 学習
- リスト
- 見て
- 探して
- たくさん
- 製
- メイン
- 主要な
- make
- 作成
- 管理します
- 管理する
- 多くの
- 地図
- マッピング
- マトリックス
- 問題
- 意味
- 意味のある
- 手段
- メンバー
- メモリ
- 方法
- メソッド
- メトリック
- 行方不明
- 混合
- モデル
- 修正されました
- モジュール
- 他には?
- もっと効率的
- さらに
- 最も
- 移動
- 掛け
- ナチュラル
- 自然
- 近く
- 必要
- 必要
- 必要とされる
- 負
- ネットワーク
- ニューラル
- ニューラルネットワーク
- 新作
- 次の
- NLP
- ノード
- 非専門家
- 概念
- 数
- Nvidia
- 得
- of
- オファー
- on
- ONE
- 開いた
- オープンソース
- OpenAI
- 操作
- 業務執行統括
- 最適な
- 最適化
- 最適化
- 最適化
- オプション
- オリジナル
- その他
- さもないと
- 出力
- 全体
- 紙素材
- 論文
- パラメーター
- 部
- 特定の
- 特に
- 部品
- のワークプ
- 完璧
- パフォーマンス
- 実行
- 相
- ピース
- プラトン
- プラトンデータインテリジェンス
- プラトデータ
- プレイ
- プレイヤー
- 再生
- ポイント
- ポリシー
- 方針
- 位置
- 可能
- 潜在的な
- 電力
- 実用的
- 練習
- 予測する
- 予測
- プ
- PLM platform.
- 前
- 確率
- 多分
- 問題
- プロセス
- ラボレーション
- 作り出す
- 生産された
- プロダクト
- 進行
- プログレッシブ
- 有望
- 提案された
- おそらく
- 実績のある
- パブリッシュ
- 公表
- RAM
- ランダム
- ランク
- むしろ
- 達した
- 達します
- 最近
- 減らします
- 電話代などの費用を削減
- 縮小
- 洗練された
- 強化学習
- リリース
- 残り
- 残っている
- 顕著
- 覚えています
- リモート
- 繰り返される
- 表します
- 表し
- の提出が必要です
- 必要
- 責任
- 制限されました
- 結果
- 結果として
- 結果
- return
- 収益
- 革命を起こす
- 報いる
- 行
- rt
- ラン
- s
- 同じ
- Save
- 節約
- シナリオ
- シナリオ
- スキーム
- を検索
- 二番
- セクション
- シード
- 選択
- 選択
- 選択
- 自己
- セッションに
- 設定
- いくつかの
- 形状
- シェアリング
- ショート
- すべき
- 表示する
- 示す
- 作品
- シグナル
- 重要
- 著しく
- 同様の
- 類似
- 簡単な拡張で
- 単純
- 単に
- から
- 状況
- サイズ
- サイズ
- 小さい
- より小さい
- Snapshot
- So
- 溶液
- 解決する
- 解決
- 一部
- ソース
- スペース
- スペース
- 特定の
- 特に
- 指定の
- スピード
- 過ごす
- 支出
- split
- 広場
- 積み上げ
- ステージ
- 標準
- start
- 開始
- 都道府県
- 最先端の
- 明記
- 米国
- 統計
- 手順
- ステップ
- 停止
- 店舗
- 保存され
- 店舗
- 簡単な
- 成功した
- そのような
- サポート
- サポート
- 合成
- 合成データ
- 総合的に
- システム
- テーラード
- 取る
- 取り
- 取得
- ターゲット
- 仕事
- タスク
- テクニック
- ターミナル
- 条件
- それ
- 未来
- グラフ
- 情報
- ステート
- アプリ環境に合わせて
- それら
- それによって
- したがって、
- ボーマン
- 三番
- 三
- 三次元の
- 介して
- 時間
- 時間がかかる
- 〜へ
- 一緒に
- トークン
- トークン化
- トークン化された
- トークン
- あまりに
- ツールキット
- top
- トーチ
- トータル
- 伝統的な
- トレーニング
- 訓練された
- トレーニング
- 列車
- 軌跡
- 変換
- 治療する
- true
- わかる
- 宇宙
- 未使用
- アップデイト
- 更新しました
- 更新版
- 更新
- アップグレード
- us
- 使用法
- つかいます
- users
- 通常
- 値
- 価値観
- さまざまな
- バージョン
- ビデオ
- ビデオゲーム
- 訪問
- 訪問
- W
- 仕方..
- この試験は
- which
- while
- 広く
- Wikipedia
- 意志
- 勝利
- 言葉
- 価値
- でしょう
- 書き込み
- 書かれた
- X
- ゼファーネット
- ゼロ