Fotó DeepMind on Unsplash
A mátrixszorzás számos rendszerben használt alapvető művelet, a neurális hálózatoktól a tudományos számítási rutinokig. Hatékony és bizonyíthatóan helyes algoritmusok megtalálása a mátrixszorzáshoz óriási hatással lehet a számítások gyorsabbá és hatékonyabbá tételére, de ez egy nagyon nagy kihívást jelentő feladat. A lehetséges algoritmusok tere óriási, és az algoritmusok felfedezésének hagyományos módszerei, mint például az ember által tervezett heurisztika vagy a kombinatorikus keresés, gyakran szuboptimálisak.
DeepMind's recently proposed AI-based solution for automated search goes far beyond human intuition. The solution consists of a deep reinforcement learning agent called AlphaTensor, built on top of alfanulla. Ezt az ügynököt egy egyjátékos TensorGame játékra képezték ki, ahol a cél az, hogy számításilag hatékony algoritmusokat fedezzen fel a mátrixszorzáshoz.
Az AlphaTensor különösen jól kezeli a nagy mátrixokat azáltal, hogy a nagy mátrixszorzásokat kisebb szorzásokra bontja. Ezenkívül az AlphaTensor a legkorszerűbb teljesítmény elérésére használható a mátrixszorzáshoz, miután egy adott hardvereszközön finomhangolták.
Az AlphaTensor nagy lehetőségeket rejt magában a mélytanulási számítástechnika felgyorsításában. A mély tanulásban sok időigényes művelet leképezhető mátrixszorzásokra. Az AlphaTensor használatával e műveletek optimalizálására a mélytanulási modellek általános teljesítménye jelentősen javítható.
Nemrég az OpenAlphaTensor, a Az AlphaTensor első nyílt forráskódú implementációjamegjelent, ami forradalmasíthatja a mély tanulási modellek számítási teljesítményét.
Mátrixszorzás tenzor
A mátrixszorzás optimalizálásában nem jártasak számára nem biztos, hogy egyszerű megérteni, hogyan lehet egy műveletet, például a mátrixszorzást leképezni egy háromdimenziós tenzorban. Megpróbálom egyszerű szavakkal és példákkal elmagyarázni.
Tekintsük a C = A*B szorzatot, ahol az egyszerűség kedvéért A és B is N méretű négyzetmátrix. A szorzási művelet leképezhető egy 3D alakú tenzorral (N^2, N^2, N^2). Az első tenzordimenzió az A lapított mátrixot, a második a B lapított mátrixot, a harmadik dimenzió a C lapított mátrixot jelenti.
A tenzornak csak bináris értékei (1 vagy 0) vannak minden bejegyzéshez. Figyeljük meg, hogy a tenzor a szorzási műveletet reprezentálja, tehát független az A és B mátrixok értékétől.
A tenzor minden bejegyzése megfelel a műveleti együtthatónak. Például a C[1,1] kiszámításához meg kell szorozni az A[1,1]-t és a B[1,1]-t is. Ezért a tenzor bejegyzés [0,0,0], amely megfelel az A[1,1], B[1,1] és C[1,1] értékeknek, 1 lesz. Ezzel szemben a C[1,1 kiszámításához ,2,1], A[1] nem szükséges. Így a T[N+0, :, XNUMX] tenzorsor csak nullákat fog tartalmazni.
Az alábbi képen egy példa látható N=2 tenzorra.
Image from DeepMind's papír kiadva Természet
Amint az a fenti ábra (b) és (c) pontjában látható, lehetséges egy algoritmus a szorzat kiszámítására a 3D tenzor dekompozíciójával. Pontosabban, az alábbi algoritmus használható tenzorbontás (az U, V, W mátrixok) mátrixszorzó algoritmussá alakítására.
Meta-algorithm parameterized for computing the matrix product C=AB introduced in DeepMind's papír
A TensorGame
A mátrixszorzáshoz hatékony algoritmusok megtalálásának problémája rendkívül nagy kihívást jelent, mivel a figyelembe veendő lehetséges algoritmusok száma sokkal nagyobb, mint az univerzum atomjainak száma, még kis mátrixszorzás esetén is.
A DeepMind ezt a problémát egyjátékos játékká alakította át, és TensorGame-nek nevezte el. Ebben a játékban a játékos kiválasztja, hogyan kombinálja a mátrixok különböző bejegyzéseit a szorzáshoz. A pontozás a helyes szorzási eredmény eléréséhez szükséges műveletek száma alapján történik. A játék akkor ér véget, amikor elérjük a nulla tenzort, vagy amikor a maximális számú lépést megtettük. A végső faktorizációt a maradék rang becslése és bizonyos optimalizálási kritériumok, például az aszimptotikus időbonyolítás vagy a gyakorlati futási idő alapján értékelik.
A TensorGame kezdeti pozíciója megfelel a mátrixszorzó tenzornak, amelyet valamilyen véletlenszerű alapon fejeznek ki.
A játék minden t lépésében a játékos felír három vektort
, amely a rang-1 tenzorokat határozza meg . A játék állapota a játékos által kiválasztott vektorok kivonásával frissül:
ahol
a mátrixszorzó tenzor.Ha a játék p lépésben végződik, ez azt jelenti, hogy a Mátrixszorzás Tenzor
p rank-1 tenzorokra bontható , azaz legalább p rangja van.A TensorGame ezután rangfelbontási algoritmusként értelmezhető, az AlphaTensor pedig a tenzor rangjának becslésére szolgáló algoritmus.
AlphaTensor architektúra
Eddig megismertük a TensorGame-et, és tisztáztuk, hogyan tekinthető a megoldása mátrixszorzó algoritmusnak. Vizsgáljuk meg most az AlphaTensor, a játékhoz használt algoritmus főbb fogalmait.
Az AlphaTensor architektúra alapvetően egy kódoló-dekódoló Transformer architektúra, ahol:
- a kódoló bemenetként a játék állapotát veszi fel , a modell által végrehajtott n korábbi művelet (általában n=7), és az aktuális művelet t időindexe. Az információ egy tenzorba van halmozva, amelynek alakja (n+1, N^2, N^2, N^2). Ezt a tenzort ezután átformálják és (három lineáris réteg felhasználásával) egy alaktenzorrá alakítják (N^2, N^2, c), ahol c a modell belső dimenziója.
- a dekóder a kódoló által megadott beágyazott vektorból autoregresszív módon generálja az n_steps műveleteket. Minden művelet a hármasok egy jelzőjének felel meg a játék tenzorát lebontó (azaz a rangját csökkentő) hármasok egyikének ábrázolása
A modellt a visszaszaporítás és a modellszínészet váltakozva képezi. A modelleljárás az adatok generálására szolgál, amelyeket aztán a modell betanításához használnak fel. A gyakorlatban a modellt szintetikusan generált adatok és a modell által a cselekvés során generált adatok keverékével képezik. A színészi lépés úgy történik, hogy veszünk egy mátrixműveletnek megfelelő 3D tenzort, és n_actors játékokat játszunk rajta. Minden szereplő vagy standard alapon, vagy alternatív alapon játszik egy játékot (a bázisváltást adott valószínűséggel alkalmazzák). Az eredményeket ezután összegyűjtik, és a szintetikus adatokkal együtt felhasználhatják a képzési lépésben.
The acting step is based on AlphaZero's Monte Carlo Tree Search (MCTS), modified to support large action spaces. In short, before choosing the action, n_sims paths are explored from the model output with a maximum future exploration of 5 steps. The probabilities generated by the model are then adjusted taking into account the generated paths. Then the action with the most promising future path(s) is chosen to continue the game.
A modell képzése közben a jutalom valójában negatív jutalom (büntetés). Abszolút értéke minden további lépéssel növekszik, amely a játék megoldásához szükséges. Ha a modell m lépést tesz meg egy TensorGame megoldásához, a játékhoz tartozó jutalom r=-m. Ha a modell nem tudja megoldani a TensorGame-et max_rank lépésekben, akkor a jutalmat a fennmaradó tenzor rangjának becslésével számítjuk ki. A rangot a tenzort alkotó mátrixok rangsorainak összegeként becsüljük. A becslés a tenzor valódi rangjának felső korlátja.
When fine-tuning the model, the penalty reward at the terminal state should also take into account the latency of the algorithm produced by the model. The reward formula becomes rt'=rt+λbt, where rt is the reward scheme described earlier, bt is the benchmark reward (non-zero only at the terminal state), and λ egy felhasználó által megadott együttható.
Az AlphaTensor által felfedezett, GPU-ra és TPU-ra szabott algoritmusok felgyorsítása (%), a DeepMind papírjából kinyerve. A gyorsulásokat a szabványos (pl. cuBLAS a GPU-hoz) mátrixszorzáshoz viszonyítva mérik ugyanazon a hardveren, és összehasonlítják a Strassen-négyzet algoritmus. forrás: DeepMind.
Nemrég szabadultam OpenAlphaTensor, az AlphaTensor első nyílt forráskódú megvalósítása. Ebben a részben a megvalósítást fogom végigjárni. Amint azt korábban tárgyaltuk, az AlphaTensor architektúra meglehetősen egyszerű, szabványos transzformátoron alapul, kódoló-dekódoló architektúrával. Az AlphaTensor legérdekesebb összetevői a kódoló rész első rétege és a műveletek mintavételi módja.
Kezdjük az első kódolási réteggel.
# 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
A fenti részletben bemutatjuk, hogyan bomlik fel a bemeneti tenzor három tenzorra, amelyeket aztán a transzformátorréteg lekérdezés-, kulcs- és értékbemeneteként használunk.
- A lapított mátrixokat reprezentáló három tenzordimenzióban (A, B, C) a bemeneti tenzor az egyes dimenziók mentén lelapul az előző műveleteket reprezentáló dimenzióval együtt. Ily módon a bemeneti tenzor minden egyes lapított másolatában a kiválasztott dimenzió az utolsó T-1 értékek és a tényleges érték összesítése a kiválasztott dimenzió összes S értékére vonatkozóan, ahol S=N^2. Filozófiailag olyan, mintha minden dimenzió esetében arra összpontosítanánk, ami az adott dimenzióban az előző cselekvések során történt.
- A skalárokat három különböző, S^2 méretű térben leképezzük, majd átformázzuk, hogy az előző pontban kapott tenzorokkal összekapcsolódjanak. Elméletileg a skalárokat egy S^2 dimenziójú beágyazási térre képezik le, majd a beágyazott információkat S vektorokká csonkolják, és egymásba rakják, hasonlóan ahhoz, ami a szöveggel tokenizáláskor történik.
- A skalár tokeneket összefűzzük az átstrukturált bemeneti tenzorral, majd bemenetként egy lineáris réteghez adjuk a skalárok+csatornatörténet fókuszinformációinak leképezéséhez a modell belső dimenziójában.
Ez a három lépés úgy értelmezhető, mint egy módja annak, hogy a modellnek információt adjon a skalárokról (mint a TensorGame időlépésében), és az egyes csatornák előző műveleteire összpontosítson.
Ami a műveletek előállítási módját illeti, érdekes megjegyezni, hogy az AlphaTensor kimenetként az u, v, w tripletet generálja, ami a tenzorrangsor csökkentését célozza. A három vektor S méretű, és mivel össze vannak kapcsolva, a modellnek egy 3*S méretű vektort kell előállítania. Az AlphaTensor RL algoritmussal van kiképezve, így minden lehetséges cselekvést valószínűségekkel kell kifejezni egy felsorolt térben, azaz a modell a különböző cselekvésekre valószínűséget állít elő. Ez azt jelenti, hogy a 3S térben minden vektort más-más művelethez kell leképezni. Ez |F|^(3S) méretű akcióteret eredményez, ahol |F| a különböző értékek száma, amelyet u, v, w eleme felvehet. Általában az értékek a (-2, -1, 0, 1, 2) értékre korlátozódnak, ami 5 elemű kardinalitást eredményez.
Itt jön egy nagy kihívás: az 5-ös méretű mátrixok mátrixszorzatának cselekvési valószínűségeinek generálásához 5^75 * 4 bájtos memóriára van szükségünk, ami ~10^44 GB memóriát jelent. Nyilvánvaló, hogy ilyen nagy akcióteret nem tudunk kezelni.
Hogyan oldjuk meg a problémát? A cselekvési valószínűségek memórialábnyomának csökkentése érdekében a hármasokat kisebb darabokra bonthatjuk, „tokenizálhatjuk”, és a darabokat generált tokenként kezeljük a transzformátor architektúrában, azaz a tokenek bemenetként adódnak a dekóderhez auto-regresszív módon. út. A fenti példában a hármasokat 15 darabra oszthatjuk, így a memóriafelhasználást 15 * 5^(75/15) * 4-re, azaz 187.5 KB-ra csökkentjük.
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), )
A fentiekben bemutatjuk a teljes művelet generálásához szükséges kódrészletet. A kódban a self.core tartalmazza a dekódoló réteget, az e tenzor pedig a kódoló réteg kimenetét jelenti. A nullát úgy tekinthetjük, mint a Az NLP modellekben a token és az n_steps darabokat reprezentáló n_steps műveletek progresszív módon jönnek létre.
A modell három mennyiséget ad vissza:
- A generált műveletek
- A teljes művelethez kapcsolódó valószínűség
- Az első művelet (az első csonk) generálásához előállított logitok, amelyeket a modell értékének kiszámításához használnak majd.
Érdemes néhány szót szánni az n_samples paraméterre. A paramétert a cselekvési lépéshez használják, és lehetővé teszi a modell számára, hogy a hármasok különböző verzióit állítsa elő, amelyeket azután a cselekvési folyamatban használt Monte Carlo Tree Search algoritmus akcióterének feltárására használnak fel. Az n_samples különböző műveletek mintavételezése a modell által generált házirend szerint történik.
Színészi lépés
Az egész algoritmus legtrükkösebb része valószínűleg a TensorGame megoldásához használt cselekvési lépés. Az algoritmust az AlphaTensor cikk nem magyarázza mélyrehatóan, mivel az a DeepMind számos korábbi tanulmányán alapul, amelyeket csak idézett és ismertként ad meg. Itt rekonstruálom az összes hiányzó részt, és lépésről lépésre elmagyarázom a megvalósításunkat.
A cselekvési lépéseket három különböző komponensbe szervezhetjük:
- A Monte-Carlo-i fakeresés
- A játék szimulációja
- A továbbfejlesztett házirend-számítás
Elemezzük őket egyenként.
Monte-Carlo Tree Search (MCTS)
A Monte Carlo Tree Search (MCTS) egy széles körben használt mesterséges intelligencia technika a játékban, különösen a társasjátékokban és a videojátékokban. Az algoritmus létrehoz egy játékfát, amely szimulálja a lehetséges lépéseket és az eredményeket, és véletlenszerű mintavételt használ az egyes lépések várható jutalmazásának értékeléséhez. Az algoritmus ezután iteratív módon kiválasztja a legmagasabb várható jutalommal járó lépést, és szimulálja az eredményeket, amíg el nem éri a terminális állapotot vagy egy meghatározott leállási feltételt. A szimulációkat arra használják, hogy megbecsüljék a győzelem valószínűségét minden lépésnél, és irányítsák a döntéshozatali folyamatot. Az MCTS hatékonynak bizonyult olyan összetett játékokban, ahol a lehetséges lépések és kimenetelek száma nagy, és sikeresen játszható mesterséges intelligenciarendszerekben, például az AlphaGo-ban használták.
Az AlphaTensor az eredeti MCTS módosított változatát használja. Pontosabban, ahelyett, hogy véletlenszerűen választanánk ki a műveletet a teljes cselekvési térből, a műveletet a modell által közvetlenül generált részhalmazok közül választják ki (a korábban bemutatott n_samples segítségével). A házirend-frissítés korrekciója ezután a Továbbfejlesztett házirend számítási lépésben kerül alkalmazásra.
Megvalósításunk során úgy döntöttünk, hogy a Monte-Carlo fáról szóló összes információt egy szótárban tároljuk, amelynek kulcsa a TensorGame állapot hash-verziója, értéke pedig magához az állapothoz kapcsolódó információ. Minden Monte-Carlo lépés egy csomópontból indul, és n_sim minijátékokat szimulál, és 5 lépésből álló horizonttal fedezi fel a jövőt. Ha a csomópontot már feltárták a korábbi szimulációkban, akkor az n_sim az előző felderítések számának figyelembevételével módosul. Minden csomópontnál a látogatások számát az N_s_a tenzor tárolja, mivel ez a tenzor tartalmazza a látogatások számát csomópont gyermekműveletenként (a modell által mintavételezettek között).
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
A fenti kód az algoritmus mikénti megvalósítását mutatja. A kód egyszerűsítése érdekében a házirend-javítás a simulate_game függvényben történik.
Játék szimuláció
A simulate_game függvény a TensorGame egy adott állapotát képviselő csomópontokból álló fa feltárásáért felelős. Ezenkívül lefuttatja a modellt, amikor egy levélcsomóponttal találkozik, és az összes csomópontinformációt a state_dict szótárban tárolja. Vessünk egy mély pillantást a megvalósítására:
@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)
Minden szimuláció három részre oszlik:
- Kiválasztás
- Terjeszkedés
- mentés
A kiválasztási részben a szimuláció a már generált fa-csomópontokon fut le, és a következő csomópontot választjuk ki a következő függvény segítségével:
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()]
A gyakorlatban az ucb függvényt maximalizáló művelet:
az adott állapothoz van kiválasztva. Itt Q a modell által generált Q értékeket jelöli, π pedig a véletlenszerű eloszlást a modellházirend segítségével mintavételezett műveletek között. N(s, a) jelenti a csomópont látogatásainak számát az a művelethez az s csomóponttól.
Amint a kiválasztási fázis elér egy levél csomópontot, és ha a szimuláció nem ért el egy végső feltételt (akár a maximális feltárás, azaz a jövő horizontja, akár a játék befejezése szempontjából), a modellt ezután az n_samples alternatív csomópontok kiválasztására használják (ezek levél lesz csomópontok az egymást követő iterációban). Ezt nevezzük bővítési fázisnak, mivel új csomópontok kerülnek a fába. Ezután az aktuális szimulációban nincs további csomópont feltárása, hanem a levél q_értéke elküldésre kerül a következő szimulációs lépéshez: a biztonsági mentés.
A biztonsági mentés minden szimuláció utolsó szakasza. A biztonsági mentés során, ha a levélcsomópont terminál állapotú volt, a rendszer kiszámítja a végső jutalmat; egyébként a levél q értékét használjuk becsült jutalomként. Ezután a jutalom visszaterjed a szimulációs pályán, frissítve mind a q_values állapotokat, mind pedig az N(s, a) látogatásszámlálót. Az alábbi részletben a jutalom visszaterjesztésének kódját mutatjuk be.
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
Továbbfejlesztett házirend-számítás
Miután az összes szimuláció lefutott, és az MCTS érdekes pillanatképet kínál a közeljövőről, ideje frissíteni az előre jelzett csomópontokhoz tartozó szabályzatot, és visszaadni őket, hogy felhasználhassák őket a képzés során. A továbbfejlesztett házirend, a pontban leírt módszert követve Hubert et al, nagy akcióterek kezelésére szolgál. Valójában kis keresési terület esetén lehetséges az MCTS során véletlenszerűen mintát venni egy akcióból az akciótérből, és kiértékelni a hatását. Hasonló megközelítés egy sokkal nagyobb cselekvési térben ahhoz vezetne, hogy minden pálya különböző utakon tér el, és végtelen mennyiségű pályára lenne szükség az értelmes statisztikák készítéséhez, majd a politika frissítéséhez. Mivel itt a minta-MCTS-t használjuk a diszperzió elkerülésére, azaz n_samples műveletek mintavételezése a modell házirendjének megfelelően történik, majd az MCTS csak kiválaszt egyet a mintavételezett műveletek közül a fa feltárása során, ezért számításnál figyelembe kell venni a mintakorrekciót. a végső frissített szabályzat, amelyet a modell betanítása során használunk.
A gyakorlatban a javított házirendet a következőképpen számítják ki
ahol
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
Vegye figyelembe, hogy megvalósításunkban, miután kiszámítottuk a házirendet az N_s_a tenzorból, vissza kell képeznünk az eredeti művelettenzorra. Valójában az N_s_a csak a modell által mintavételezett műveleteket veszi figyelembe, míg a végső szabályzatnak tartalmaznia kell valószínűségeket a fel nem vizsgált műveletekre is.
Különbségek a ChatGPT képzési algoritmussal kapcsolatban
AlphaTensor is the latest member of the AlphaGo/AlphaZero family of artificial intelligence methods by DeepMind. These methods are based on the Monte Carlo Tree Search (MCTS) algorithm, which has been refined and enhanced by DeepMind to tackle increasingly complex tasks. Another AI system, OpenAI's ChatGPT, which has caused a lot of buzz for its remarkable performance, was trained with a different approach, called Reinforcement Learning with Human Feedback (RLHF).
Az RLHF egy finomhangoló technika, amellyel a nyelvi modelleket úgy hangolják, hogy egy sor írott utasítást kövessenek. Az emberi preferenciákat jutalomjelként használja a modell finomhangolására, ezáltal a nyelvi modell viselkedését az emberek egy bizonyos csoportjának kinyilvánított preferenciáihoz igazítja, nem pedig az „emberi értékek” valamilyen tágabb fogalmához.
Ezzel szemben az MCTS egy fa alapú keresési algoritmus, amelyet a játékok optimális lépéseinek meghatározására használnak. Simulálja a lehetséges lépéseket, és frissíti az egyes lépések értékeit azok eredményei alapján, irányítva a legjobb lépés kiválasztását.
Az RLHF adatokat gyűjt az emberek által írt bemutatókból és az AI-modellek ember által jelzett összehasonlításából, és egy jutalommodellt képez ki, amely előrejelzi egy adott embercsoport preferenciáit. A jutalommodellt ezután az AI-modellek finomhangolására használják. Az MCTS ezzel szemben szimulációkat és értékeléseket használ a legjobb döntés meghatározásához.
Bár eltérő megközelítésekről van szó, az RLHF és az MCTS hasonlóságokat is mutat. Mindkét mesterséges intelligencia-technika döntéshozatali és problémamegoldó módszereket használ, és mindkettő próba-szerencse megközelítést alkalmaz a különböző lehetőségek feltárására és a rendelkezésre álló információk alapján történő döntéshozatalra. Mindkettő iteratív folyamat, amely idővel javul, ahogy egyre több információ és tapasztalat gyűlik össze.
Az RLHF és az MCTS közötti választás az adott feladattól függ. Az RLHF ideális, ha nincs egyértelmű mérőszám a modell teljesítményének értékelésére, míg az MCTS hatékonynak bizonyult olyan játékszerű feladatokban, ahol a tudás és a jövő feltárása jelentős előnyt jelent a modellnek.
Kódoptimalizálás az AlphaTensor edzéshez
Az AlphaTensor edzési algoritmus megvalósításához meg kell találni a tökéletes kompromisszumot az edzési sebesség és a memóriafelhasználás között. Amint az a Modell részben látható, az akciótokenizálás egyszerű figyelembevétele sok memóriát takaríthat meg, de a túlzottan agresszív akcióterület-csökkentés a pontosság csökkenéséhez és a teljesítmény csökkenéséhez is vezethet. Ez utóbbi azért történik, mert az összes tokent szekvenciálisan, autoregresszív módon generálja a modelldekóder. Ezért a következtetési idő lineárisan növekszik a műveletenkénti tokenek számával, miután az akciótér softmax-ja már nem jelenti a szűk keresztmetszetet.
Az AlphaTensor tréning felállításakor a fő nehézségeket a színészi folyamat kezelésében találtuk. Ha a tenzorokat nem a megfelelő formátumban tárolják, az MCTS könnyen ellenőrizetlen memóriahasználat-növekedést okozhat. Másrészt, ha az egyes szimulációk során tárolt tenzorok számát túlságosan csökkentik, az MCTS végtelenül sok időt tölthet a szükséges állapotok újraszámításával.
Let's take an example of the game simulation step, where the game is explored by looking at possible future scenarios. For each state, if we don't save the actions generated by the model and we decide to save only the random seed used to sample the actions from the policy, then each time we explore a tree node we would have to recompute the policy and then sample the actions. Clearly, we decided to store the sampled actions to save time and to avoid having to manage model sharing between different processes in the case of MCTS exploration parallelization. However, just saving the actions was not enough to get a sufficiently efficient acting step. In fact, the time for converting the n_steps actions into the (u, v, w) triplet, reducing the game tensor state and creating the new3D tensors from the n_samples actions would easily be a bottleneck for the whole training. Secondly, we didn't want to store all possible future states for each sampled action, as this would have a huge impact on the memory used by the algorithm. Suppose we set n_samples=32, n=7 and N=5, and let's remember that N is the size of the square matrix product we want to reduce and n is the number of previous actions remembered by the model. In this situation, each state tensor would have the form (8, 25, 25, 25), which multiplied by 32 would result in 3282525254 bájt a grafikon minden csomópontjához. Ha figyelembe vesszük, hogy a bővítési fázisban minden szimuláció egy új csomópontot generál (és n_sim=200), a végső memóriafelhasználásunk 200 lenne.328252525*4 = 3.2 GB egyedül az első MCTS-csomóponthoz. A legrosszabb forgatókönyv szerint a működő max_rank csomópontok (ahol max_rank = 150) feltárása esetén ez 150 * 3.2 GB = 480 GB teljes memóriafelhasználást eredményezne a RAM memóriában (vagy a GPU memóriájában, ha minden tenzor a GPU-n van tárolva). . A képzést a munkaállomásunkon 128 GB RAM-mal és 48 GB GPU memóriával bonyolítottuk le, így csökkenteni kellett a memóriafelhasználást.
Since we didn't want to increase the execution time, we adopted an optimization that exploits the redundancy in the state tensors produced. In fact, the tensors have n-1 previous actions in common, which can then be stored once and not repeated for each stored tensor. This results in a memory reduction of 2/7~28%, meaning that in the worst-case 137GB can be stored. At this point, by simply pruning the unused part of the tree (such as the unselected trajectories) and storing the tensors in CPU memory, we were able to avoid any memory error during training.
Mivel az OpenAlphaTensor nyílt forráskódú, számos izgalmas út nyílik a további fejlesztésre.
Természetes folyamat az OpenAlphaTensor finomhangolása a célhardvereken. Ez várhatóan nagyon versenyképes számítási teljesítményhez vezet. Többet fogok közzétenni az OpenAlphaTensor teljesítményéről különböző hardvereken GitHub. A cikk írásakor az OpenAlphaTensor képzésen vett részt.
Egy másik fontos előrelépés a távoli fordítás támogatása, amely lehetővé teszi a felhasználók számára, hogy szélső eszközökre optimalizált algoritmusokat készítsenek. Ezt úgy érhetjük el, hogy az OpenAlphaTensor modellt egy szerveren tároljuk, míg a mátrixszorzó algoritmust különböző hardvereken értékeljük ki.
Fontos lehet a különböző fordítók támogatásának kiterjesztése a késleltetés alapú jutalomkorrekció kiszámításához. A különböző fordítók különböző optimalizált algoritmusokhoz vezethetnek egy adott hardveren. Például a DeepMind dokumentum ígéretes eredményeket mutatott a JAX és az XLA fordító használatával TPU és Nvidia GPU-kon. Érdekes lenne ezt kiértékelni az NCCL segítségével Nvidián vagy LLVM-mel a CPU-kon.
Végül továbbra is komoly nyitott kihívás marad a modell és a betanító algoritmus kiterjesztése a nagyobb mátrixméretek támogatására. Az OpenAlphaTensor jelenleg 5-ös maximális mátrixméretet támogat, de alkalmazható úgy, hogy a nagyobb mátrixszorzásokat apró, 5-nél kisebb méretű MM-csoportokra osztja. Ez a megközelítés szuboptimális, és a redukciót közvetlenül a nagy tenzoron hajtja végre, amely megfelel a A teljes MM elméletileg jobb eredményekhez vezethet.
Diego Fiori is the CTO of Nebuly AI, a company committed to making AI optimization part of every developer's toolkit.
- SEO által támogatott tartalom és PR terjesztés. Erősödjön még ma.
- Platoblockchain. Web3 metaverzum intelligencia. Felerősített tudás. Hozzáférés itt.
- Forrás: 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
- :is
- ][p
- $ UP
- 1
- 3d
- 8
- a
- Képes
- Rólunk
- felett
- Abszolút
- gyorsuló
- Szerint
- Eszerint
- Fiók
- pontosság
- Elérése
- elért
- Akció
- cselekvések
- tulajdonképpen
- hozzáadott
- További
- Beállított
- fogadott
- előre
- Előny
- Után
- Ügynök
- összesítés
- agresszív
- AI
- AI rendszerek
- célok
- algoritmus
- algoritmusok
- Minden termék
- lehetővé téve
- lehetővé teszi, hogy
- kizárólag
- már
- alternatív
- között
- összeg
- elemez
- és a
- Másik
- alkalmazott
- megközelítés
- megközelít
- építészet
- VANNAK
- cikkben
- mesterséges
- mesterséges intelligencia
- AS
- kijelölt
- társult
- At
- Automatizált
- elérhető
- elkerülve
- vissza
- mentés
- alapján
- Alapvetően
- alap
- BE
- mert
- válik
- előtt
- hogy
- lent
- benchmark
- BEST
- Jobb
- között
- Túl
- bizottság
- Társasjátékok
- köteles
- tágabb
- BT
- épít
- épült
- by
- hívott
- TUD
- nem tud
- eset
- Okoz
- okozott
- bizonyos
- kihívás
- kihívást
- változik
- csatorna
- ChatGPT
- gyermek
- választás
- választja
- választott
- idézett
- világos
- világosan
- kód
- összegyűjti
- össze
- elkötelezett
- Közös
- vállalat
- képest
- versenyképes
- bonyolult
- bonyolultság
- alkatrészek
- áll
- kompromisszum
- számítás
- számítási teljesítmény
- Kiszámít
- számítástechnika
- fogalmak
- fogalmilag
- feltétel
- bizalom
- Fontolja
- figyelembe vett
- figyelembe véve
- úgy véli,
- fogyasztás
- tartalmaz
- folytatódik
- kontraszt
- átalakított
- Mag
- Megfelelő
- megfelel
- tudott
- Számláló
- CPU
- teremt
- létrehozása
- kritériumok
- CTO
- Jelenlegi
- Jelenleg
- dátum
- foglalkozó
- dönt
- határozott
- döntés
- Döntéshozatal
- határozatok
- mély
- mély tanulás
- DeepMind
- függ
- leírt
- Határozzuk meg
- Fejlesztő
- Fejlesztés
- eszköz
- Eszközök
- DICT
- különböző
- nehézségek
- Dimenzió
- méretek
- közvetlenül
- felfedez
- felfedezése
- tárgyalt
- terjesztés
- megosztott
- le-
- Csepp
- alatt
- e
- minden
- Korábban
- könnyen
- él
- Hatékony
- hatékony
- bármelyik
- elem
- elemek
- beágyazott
- vége
- fokozott
- hatalmas
- elég
- belépés
- hiba
- becslés
- becsült
- Eter (ETH)
- értékelni
- értékelték
- értékelő
- értékelések
- Még
- Minden
- példa
- példák
- izgalmas
- végrehajtás
- terjeszkedés
- várható
- tapasztalat
- Magyarázza
- magyarázható
- hasznosítja
- kutatás
- feltárása
- feltárt
- Feltárása
- kifejezve
- terjed
- kiterjedő
- rendkívüli módon
- meglehetősen
- család
- gyorsabb
- Visszacsatolás
- kevés
- Ábra
- utolsó
- megtalálása
- vezetéknév
- Úszó
- Összpontosít
- következik
- következő
- Lábnyom
- A
- forma
- formátum
- képlet
- talált
- ból ből
- Tele
- funkció
- alapvető
- további
- további fejlődés
- jövő
- játék
- Games
- generál
- generált
- generál
- generáló
- kap
- szerzés
- Ad
- adott
- Giving
- cél
- Goes
- jó
- GPU
- GPU
- grafikon
- nagy
- Csoport
- Csoportok
- növekszik
- Növekedés
- útmutató
- kéz
- Kezelés
- történt
- megtörténik
- hardver
- hardver eszköz
- hardvereszközök
- Legyen
- tekintettel
- itt
- legnagyobb
- horizont
- Hogyan
- How To
- azonban
- HTTPS
- hatalmas
- emberi
- i
- BETEG
- ideális
- IDX
- kép
- Hatás
- végre
- végrehajtás
- fontos
- javul
- javított
- in
- Növelje
- Növeli
- egyre inkább
- független
- index
- információ
- kezdetben
- bemenet
- helyette
- utasítás
- Intelligencia
- érdekes
- belső
- Bevezetett
- intuíció
- IT
- ismétlés
- ITS
- maga
- jpg
- KDnuggets
- Tart
- Kulcs
- tudás
- ismert
- nyelv
- nagy
- nagyobb
- keresztnév
- Késleltetés
- legutolsó
- réteg
- tojók
- vezet
- tanult
- tanulás
- Lista
- néz
- keres
- Sok
- készült
- Fő
- fontos
- csinál
- Gyártás
- kezelése
- kezelése
- sok
- térkép
- térképészet
- Mátrix
- Anyag
- maximális
- jelenti
- jelentőségteljes
- eszközök
- tag
- Memory design
- módszer
- mód
- metrikus
- hiányzó
- keverék
- modell
- modellek
- módosított
- modul
- több
- hatékonyabb
- Ráadásul
- a legtöbb
- mozog
- mozog
- szorozva
- Természetes
- Természet
- Közel
- elengedhetetlen
- Szükség
- szükséges
- negatív
- hálózatok
- ideg-
- neurális hálózatok
- Új
- következő
- NLP
- csomópont
- csomópontok
- nem szakértők
- fogalom
- szám
- Nvidia
- kapott
- of
- Ajánlatok
- on
- ONE
- nyitva
- nyílt forráskódú
- OpenAI
- működés
- Művelet
- optimálisan
- optimalizálás
- Optimalizálja
- optimalizált
- Opciók
- eredeti
- Más
- másképp
- teljesítmény
- átfogó
- Papír
- papírok
- paraméter
- rész
- különös
- különösen
- alkatrészek
- Emberek (People)
- tökéletes
- teljesítmény
- előadó
- fázis
- darabok
- Plató
- Platón adatintelligencia
- PlatoData
- játszani
- játékos
- játék
- pont
- Politikák
- politika
- pozíció
- lehetséges
- potenciális
- hatalom
- Gyakorlati
- gyakorlat
- előre
- jósolt
- preferenciák
- bemutatott
- előző
- valószínűség
- valószínűleg
- Probléma
- folyamat
- Folyamatok
- gyárt
- Készült
- Termékek
- haladás
- progresszív
- biztató
- javasolt
- bizonyíthatóan
- igazolt
- közzétesz
- közzétett
- RAM
- véletlen
- soraiban
- Inkább
- elérte
- Elér
- nemrég
- csökkenteni
- Csökkent
- csökkentő
- kifinomult
- megerősítő tanulás
- felszabaduló
- megmaradó
- maradványok
- figyelemre méltó
- eszébe jut
- távoli
- megismételt
- képviselő
- jelentése
- kötelező
- megköveteli,
- felelős
- korlátozott
- eredményez
- kapott
- Eredmények
- visszatérés
- Visszatér
- forradalmasítani
- Jutalom
- SOR
- rt
- futás
- s
- azonos
- Megtakarítás
- megtakarítás
- forgatókönyv
- forgatókönyvek
- rendszer
- Keresés
- Második
- Rész
- mag
- kiválasztott
- kiválasztása
- kiválasztás
- MAGA
- készlet
- beállítás
- számos
- Alak
- megosztás
- rövid
- kellene
- előadás
- mutatott
- Műsorok
- Jel
- jelentős
- jelentősen
- hasonló
- hasonlóságok
- Egyszerű
- egyszerűség
- egyszerűen
- tettetés
- óta
- helyzet
- Méret
- méretek
- kicsi
- kisebb
- Pillanatkép
- So
- megoldások
- SOLVE
- Megoldása
- néhány
- forrás
- Hely
- terek
- különleges
- kifejezetten
- meghatározott
- sebesség
- költ
- Költési
- osztott
- négyzet
- egymásra rakva
- Színpad
- standard
- kezdet
- kezdődik
- Állami
- csúcs-
- meghatározott
- Államok
- statisztika
- Lépés
- Lépései
- megállítás
- tárolni
- memorizált
- árnyékolók
- egyértelmű
- sikeres
- ilyen
- támogatás
- Támogatja
- szintetikus
- szintetikus adatok
- szintetikusan
- rendszer
- Systems
- szabott
- Vesz
- tart
- bevétel
- cél
- Feladat
- feladatok
- technikák
- terminál
- feltételek
- hogy
- A
- A jövő
- A grafikon
- az információ
- Az állam
- azok
- Őket
- ezáltal
- ebből adódóan
- Ezek
- Harmadik
- három
- háromdimenziós
- Keresztül
- idő
- időigényes
- nak nek
- együtt
- jelképes
- tokenizálás
- Vezérjeles
- tokenek
- is
- eszköztár
- felső
- fáklya
- Végösszeg
- hagyományos
- Vonat
- kiképzett
- Képzések
- vonatok
- röppálya
- át
- kezelésére
- igaz
- megért
- Világegyetem
- felhasználatlan
- Frissítések
- frissítve
- Frissítés
- frissítése
- frissítés
- us
- Használat
- használ
- Felhasználók
- rendszerint
- érték
- Értékek
- különféle
- változat
- videó
- videojátékok
- Látogat
- Látogatók
- W
- Út..
- Mit
- ami
- míg
- széles körben
- Wikipedia
- lesz
- nyerő
- val vel
- szavak
- munkaállomás
- érdemes
- lenne
- írás
- írott
- X
- zephyrnet
- nulla