Hier teile ich einen KI-Code, einen Transformer, der mit allen Berechnungen und vollständigen Ableitungen für Backpropagation und Attention in VB.net 2010 entworfen wurde.
Wer interessiert ist, kann gerne ein bisschen stöbern, und frei kommentieren, es handelt sich um unbezahlten Inhalt.
<Serializable()>
Public Class RedTransformerSoloDecoder_Matrix00
#Region "Konfiguration und Hilfsfunktionen"
Private Const clippingThreshold As Single = 5.0F
Private Const epsilon As Single = 0.00000001F ' Leicht erhöht für mehr Stabilität
Öffentlich Struktur TrainingResult
Öffentlich Verlust Als Einzel
Ende Struktur
Öffentlich Klasse TrainingBatch
Öffentlich EingangsIds Als Liste(Of Liste(Of Ganzzahl))
Öffentliches AufmerksamkeitMasks Als Liste(Of Liste(Of Boolean))
Öffentlich Labels Als Liste(Of Liste(Of Ganzzahl))
Ende Klasse
Privat Gemeinsame Funktion ClipGradient(ByVal value Als Einzel) Als Einzel
Rückgabe Math.Max(Math.Min(value, clippingThreshold), -clippingThreshold)
Ende Funktion
Privat Gemeinsame Sub AddMatrices(ByRef baseMatrix() Als Einzel, ByVal matrixToAdd() Als Einzel)
Wenn baseMatrix Ist Nichts Oder matrixToAdd Ist Nichts Oder baseMatrix.Länge <> matrixToAdd.Länge Dann Rückgabe
Für i = 0 Bis baseMatrix.Länge - 1
baseMatrix(i) += matrixToAdd(i)
Nächster
Ende Sub
Privat Gemeinsame Sub AddVectorToMatrixRows(ByRef baseMatrix() Als Einzel, ByVal nRows Als Ganzzahl, ByVal nCols Als Ganzzahl, ByRef vectorToAdd() Als Einzel)
Wenn baseMatrix Ist Nichts Oder vectorToAdd Ist Nichts Dann Beenden Sub
Wenn nCols <> vectorToAdd.Länge Dann Beenden Sub
Für r Als Ganzzahl = 0 Bis nRows - 1
Dim offset Als Ganzzahl = r * nCols
Für c Als Ganzzahl = 0 Bis nCols - 1
baseMatrix(offset + c) += vectorToAdd(c)
Nächster
Nächster
Ende Sub
#End Region
#Region "Mathematische Operationen (Vollständig und Robuster in Einzel)"
Öffentlich Klasse MatematicasOptimizadas
Öffentliches Gemeinsames Sub TransponerInArray(ByVal src() Als Einzel, ByVal dst() Als Einzel, ByVal zeilen Als Ganzzahl, ByVal cols Als Ganzzahl)
Wenn zeilen < 0 Oder cols < 0 Dann Werfen Neue ArgumentException("Zeilen und Spalten müssen >= 0 sein.")
Wenn src Ist Nichts Dann Werfen Neue ArgumentNullException("src")
Wenn dst Ist Nichts Dann Werfen Neue ArgumentNullException("dst")
Wenn src.Länge <> zeilen * cols Dann Werfen Neue ArgumentException("Ungültige Länge von src für (zeilen * cols).")
Wenn dst.Länge <> cols * rows Dann Werfen Neue ArgumentException("Ungültige Länge von dst für (cols * rows).")
Für r Als Ganzzahl = 0 Bis zeilen - 1
Dim baseSrc Als Ganzzahl = r * cols
Für c Als Ganzzahl = 0 Bis cols - 1
dst(c * zeilen + r) = src(baseSrc + c)
Nächster
Nächster
Ende Sub
Öffentliches Gemeinsames Sub MultiplicarMatrizMatriz(ByVal A() Als Einzel, ByVal B() Als Einzel, ByVal C() Als Einzel, ByVal m Als Ganzzahl, ByVal n Als Ganzzahl, ByVal p Als Ganzzahl)
Wenn m < 0 Oder n < 0 Oder p < 0 Dann Werfen Neue ArgumentException("m, n y p müssen >= 0 sein.")
Wenn m = 0 Oder n = 0 Oder p = 0 Dann
Wenn C Ist Nicht Nichts Und C.Länge >= m * p Dann Array.Clear(C, 0, m * p)
Rückgabe
Ende Wenn
Wenn A Ist Nichts Dann Werfen Neue ArgumentNullException("A")
Wenn B Ist Nichts Dann Werfen Neue ArgumentNullException("B")
Wenn C Ist Nichts Dann Werfen Neue ArgumentNullException("C")
Wenn A.Länge <> m * n Oder B.Länge <> n * p Oder C.Länge <> m * p Dann
Werfen Neue ArgumentException("Ungültige Matrixdimensionen.")
Ende Wenn
Array.Clear(C, 0, m * p)
Parallel.For(0, m, Sub(i)
Dim aRowBase Als Ganzzahl = i * n
Dim cRowBase Als Ganzzahl = i * p
Für j Als Ganzzahl = 0 Bis p - 1
Dim sum Als Einzel = 0.0F
Für k Als Ganzzahl = 0 Bis n - 1
sum += A(aRowBase + k) * B(k * p + j)
Nächster
C(cRowBase + j) = sum
Nächster
Ende Sub)
Ende Sub
Öffentliches Gemeinsames Sub MultiplicarMatrizMatrizT2(ByVal A() Als Einzel, ByVal B_T() Als Einzel, ByVal C() Als Einzel, ByVal m Als Ganzzahl, ByVal n Als Ganzzahl, ByVal p Als Ganzzahl)
Wenn m < 0 Oder n < 0 Oder p < 0 Dann Werfen Neue ArgumentException("m, n y p müssen >= 0 sein.")
Wenn m = 0 Oder n = 0 Oder p = 0 Dann
Wenn C Ist Nicht Nichts Und C.Länge >= m * p Dann Array.Clear(C, 0, m * p)
Rückgabe
Ende Wenn
Wenn A Ist Nichts Dann Werfen Neue ArgumentNullException("A")
Wenn B_T Ist Nichts Dann Werfen Neue ArgumentNullException("B_T")
Wenn C Ist Nichts Dann Werfen Neue ArgumentNullException("C")
Wenn A.Länge <> m * n Oder B_T.Länge <> p * n Oder C.Länge <> m * p Dann
Werfen Neue ArgumentException("Ungültige Matrixdimensionen.")
Ende Wenn
Array.Clear(C, 0, m * p)
Parallel.For(0, m, Sub(i)
Dim aBase Als Ganzzahl = i * n
Dim cBase Als Ganzzahl = i * p
Für j Als Ganzzahl = 0 Bis p - 1
Dim s Als Einzel = 0.0F
Dim btBase Als Ganzzahl = j * n
Für k Als Ganzzahl = 0 Bis n - 1
s += A(aBase + k) * B_T(btBase + k)
Nächster
C(cBase + j) = s
Nächster
Ende Sub)
Ende Sub
Öffentliches Gemeinsames Sub MultiplicarMatrizT1Matriz(ByVal A() Als Einzel, ByVal B() Als Einzel, ByVal C() Als Einzel, ByVal m Als Ganzzahl, ByVal n Als Ganzzahl, ByVal p Als Ganzzahl)
Wenn m < 0 Oder n < 0 Oder p < 0 Dann Werfen Neue ArgumentException("m, n y p müssen >= 0 sein.")
Wenn m = 0 Oder n = 0 Oder p = 0 Dann
Wenn C Ist Nicht Nichts Und C.Länge >= n * p Dann Array.Clear(C, 0, n * p)
Rückgabe
Ende Wenn
Wenn A Ist Nichts Dann Werfen Neue ArgumentNullException("A")
Wenn B Ist Nichts Dann Werfen Neue ArgumentNullException("B")
Wenn C Ist Nichts Dann Werfen Neue ArgumentNullException("C")
Wenn A.Länge <> m * n Oder B.Länge <> m * p Oder C.Länge <> n * p Dann
Werfen Neue ArgumentException("Ungültige Matrixdimensionen.")
Ende Wenn
Array.Clear(C, 0, n * p)
Parallel.For(0, n, Sub(i)
Dim cBase Als Ganzzahl = i * p
Für j Als Ganzzahl = 0 Bis p - 1
Dim sum Als Einzel = 0.0F
Für k Als Ganzzahl = 0 Bis m - 1
sum += A(k * n + i) * B(k * p + j) ' A^T(i, k) * B(k, j)
Nächster
C(cBase + j) = sum
Nächster
Ende Sub)
Ende Sub
Öffentliches Gemeinsames Sub StableSoftmaxMatrix(ByVal inp() Als Einzel, ByVal output() Als Einzel, ByVal nRows Als Ganzzahl, ByVal nCols Als Ganzzahl)
Wenn nRows = 0 Oder nCols = 0 Dann Rückgabe
Parallel.For(0, nRows, Sub(r)
Dim offset Als Ganzzahl = r * nCols
Dim maxVal Als Einzel = Einzel.NegativeInfinity
Für c Als Ganzzahl = 0 Bis nCols - 1
Dim v Als Einzel = inp(offset + c)
Wenn v > maxVal Dann maxVal = v
Nächster
Wenn Einzel.IsNegativeInfinity(maxVal) Dann maxVal = 0.0F
Dim sumExp Als Einzel = 0.0F
Für c Als Ganzzahl = 0 Bis nCols - 1
Dim eVal Als Einzel = CSng(Math.Exp(inp(offset + c) - maxVal))
Ausgabe(offset + c) = eVal
sumExp += eVal
Nächster
Wenn sumExp > epsilon Dann
Dim invSum Als Einzel = 1.0F / sumExp
Für c Als Ganzzahl = 0 Bis nCols - 1 : output(offset + c) *= invSum : Nächster
Sonst
Dim uniformProb Als Einzel = 1.0F / nCols
Für c Als Ganzzahl = 0 Bis nCols - 1 : output(offset + c) = uniformProb : Nächster
Ende Wenn
Ende Sub)
Ende Sub
Öffentliches Gemeinsames Sub SoftmaxGradMatrix(ByVal y() Als Einzel, ByVal grad_y() Als Einzel, ByVal grad_x() Als Einzel, ByVal nRows Als Ganzzahl, ByVal nCols Als Ganzzahl)
Wenn nRows = 0 Oder nCols = 0 Dann
Wenn grad_x Ist Nicht Nichts Und grad_x.Länge >= nRows * nCols Dann Array.Clear(grad_x, 0, nRows * nCols)
Rückgabe
Ende Wenn
Wenn y Ist Nichts Oder grad_y Ist Nichts Oder grad_x Ist Nichts Oder y.Länge <> nRows * nCols Oder grad_y.Länge <> nRows * nCols Oder grad_x.Länge <> nRows * nCols Dann
Werfen Neue ArgumentException("Ungültige Argumente für SoftmaxGradMatrix.")
Ende Wenn
Parallel.For(0, nRows, Sub(r)
Dim off Als Ganzzahl = r * nCols
Dim dotProd Als Einzel = 0.0F
Für c Als Ganzzahl = 0 Bis nCols - 1 : dotProd += y(off + c) * grad_y(off + c) : Nächster
Für c Als Ganzzahl = 0 Bis nCols - 1 : grad_x(off + c) = y(off + c) * (grad_y(off + c) - dotProd) : Nächster
Ende Sub)
Ende Sub
Öffentliches Gemeinsames Sub LayerNormMatrix(ByVal x() Als Einzel, ByVal gamma() Als Einzel, ByVal beta() Als Einzel, ByVal output() Als Einzel, ByVal nRows Als Ganzzahl, ByVal nCols Als Ganzzahl, Optional ByVal cache_x_hat() Als Einzel = Nichts, Optional ByVal cache_std_dev() Als Einzel = Nichts, Optional ByVal isTraining Als Boolean = Falsch)
Wenn nRows = 0 Oder nCols = 0 Dann Rückgabe
Parallel.For(0, nRows, Sub(r)
Dim offset Als Ganzzahl = r * nCols
Dim sum Als Einzel = 0.0F
Für c Als Ganzzahl = 0 Bis nCols - 1 : sum += x(offset + c) : Nächster
Dim mean Als Einzel = sum / nCols
Dim sumSq Als Einzel = 0.0F
Für c Als Ganzzahl = 0 Bis nCols - 1
Dim d Als Einzel = x(offset + c) - mean
sumSq += d * d
Nächster
Dim stdDev Als Einzel = CSng(Math.Sqrt(sumSq / nCols + epsilon))
Dim invStd Als Einzel = 1.0F / stdDev
Für c Als Ganzzahl = 0 Bis nCols - 1
Dim x_hat_val Als Einzel = (x(offset + c) - mean) * invStd
output(offset + c) = x_hat_val * gamma(c) + beta(c)
Wenn isTraining Und cache_x_hat Ist Nicht Nichts Dann
cache_x_hat(offset + c) = x_hat_val
Ende Wenn
Nächster
Wenn isTraining Und cache_std_dev Ist Nicht Nichts Dann
cache_std_dev(r) = stdDev
Ende Wenn
Ende Sub)
Ende Sub
Öffentliches Gemeinsames Sub LayerNormGradMatrix(ByVal gradOutput() Als Einzel, ByVal x_hat() Als Einzel, ByVal gamma() Als Einzel, ByVal stdDevs() Als Einzel, ByVal gradInput() Als Einzel, ByVal gradGamma() Als Einzel, ByVal gradBeta() Als Einzel, ByVal nRows Als Ganzzahl, ByVal nCols Als Ganzzahl)
Wenn nRows = 0 Oder nCols = 0 Dann Rückgabe
Dim bagGradGamma Als Neue Concurrent.ConcurrentBag(Of Einzel())()
Dim bagGradBeta Als Neue Concurrent.ConcurrentBag(Of Einzel())()
Parallel.For(0, nRows, Sub(r)
Dim off Als Ganzzahl = r * nCols
Dim invStd Als Einzel = 1.0F / stdDevs(r)
Dim term1_sum Als Einzel = 0.0F
Dim term2_sum Als Einzel = 0.0F
Dim d_x_hat_row(nCols - 1) Als Einzel
Dim localGradGamma(nCols - 1) Als Einzel
Dim localGradBeta(nCols - 1) Als Einzel
Für c Als Ganzzahl = 0 Bis nCols - 1
Dim gOut Als Einzel = gradOutput(off + c)
Dim xh Als Einzel = x_hat(off + c)
localGradGamma(c) += gOut * xh
localGradBeta(c) += gOut
d_x_hat_row(c) = gOut * gamma(c)
term1_sum += d_x_hat_row(c)
term2_sum += d_x_hat_row(c) * xh
Nächster
Für c Als Ganzzahl = 0 Bis nCols - 1
gradInput(off + c) = invStd * (d_x_hat_row(c) - (term1_sum / nCols) - x_hat(off + c) * (term2_sum / nCols))
Nächster
bagGradGamma.Add(localGradGamma)
bagGradBeta.Add(localGradBeta)
Ende Sub)
Array.Clear(gradGamma, 0, gradGamma.Length)
Array.Clear(gradBeta, 0, gradBeta.Länge)
Für Jede localGradG In bagGradGamma
Für c = 0 Bis nCols - 1 : gradGamma(c) += localGradG(c) : Nächster
Nächster
Für Jede localGradB In bagGradBeta
Für c = 0 Bis nCols - 1 : gradBeta(c) += localGradB(c) : Nächster
Nächster
Ende Sub
Öffentliches Gemeinsames Sub GeLUMatrix(ByVal x() Als Einzel, ByVal nElements Als Ganzzahl)
Wenn nElements = 0 Dann Rückgabe
Parallel.For(0, nElements, Sub(i)
Dim v Als Einzel = x(i)
x(i) = 0.5F * v * (1.0F + CSng(Math.Tanh(CSng(Math.Sqrt(2.0F / Math.PI)) * (v + 0.044715F * v * v * v))))
Ende Sub)
Ende Sub
Öffentliches Gemeinsames Sub GeLUGradMatrix(ByVal grad_output() Als Einzel, ByVal net_input() Als Einzel, ByVal grad_input() Als Einzel, ByVal nElements Als Ganzzahl)
Wenn nElements = 0 Dann Rückgabe
Parallel.For(0, nElements, Sub(i)
Dim x Als Einzel = net_input(i)
Dim x2 Als Einzel = x * x
Dim x3 Als Einzel = x2 * x
Dim inner Als Einzel = CSng(Math.Sqrt(2.0F / Math.PI)) * (x + 0.044715F * x3)
Dim tanhVal Als Einzel = CSng(Math.Tanh(inner))
Dim sech2 Als Einzel = 1.0F - tanhVal * tanhVal
Dim dInner Als Einzel = CSng(Math.Sqrt(2.0 / Math.PI)) * (1.0F + 3.0F * 0.044715F * x2)
Dim grad Als Einzel = 0.5F * (1.0F + tanhVal) + 0.5F * x * sech2 * dInner
grad_input(i) = grad_output(i) * grad
Ende Sub)
Ende Sub
Öffentliches Gemeinsames Sub SumMatrixRows(ByVal matrix() Als Einzel, ByVal result_vector() Als Einzel, ByVal nRows Als Ganzzahl, ByVal nCols Als Ganzzahl)
Wenn nRows = 0 Oder nCols = 0 Dann Rückgabe
Array.Clear(result_vector, 0, result_vector.Länge)
Für r Als Ganzzahl = 0 Bis nRows - 1
Dim off Als Ganzzahl = r * nCols
Für c Als Ganzzahl = 0 Bis nCols - 1
result_vector(c) += matrix(off + c)
Nächster
Nächster
Ende Sub
Ende Klasse
#End Region
#Region "Modellstruktur und Parameter (Einzelpräzision)"
<JsonProperty()> Privat ReadOnly vocabSize, hiddenDim, nLayers, nHeads Als Ganzzahl
<JsonProperty()> Privat ReadOnly headDim, ffnHiddenDim, maxSeqLen Als Ganzzahl
<JsonProperty()> Privat ReadOnly weightDecay Als Einzel, dropoutRate Als Einzel
<Serializable()> Öffentlich Klasse ParameterSet
<JsonProperty()> Öffentlich W, m, v Als Einzel()
Öffentliches Sub Neu(ByVal size Als Ganzzahl)
Wenn size > 0 Dann ReDim W(size - 1), m(size - 1), v(size - 1)
Ende Sub
Ende Klasse
<Serializable()> Öffentlich Klasse LayerParameters
<JsonProperty()> Öffentlich Weights, Biases Als ParameterSet
Öffentliches Sub Neu(ByVal numOutputs Als Ganzzahl, ByVal numInputs Als Ganzzahl)
Weights = Neue ParameterSet(numOutputs * numInputs)
Biases = Neue ParameterSet(numOutputs)
Ende Sub
Ende Klasse
<Serializable()> Öffentlich Klasse LayerNormParameters
<JsonProperty()> Öffentlich Gamma, Beta Als ParameterSet
Öffentliches Sub Neu(ByVal size Als Ganzzahl)
Gamma = Neue ParameterSet(größe)
Beta = Neue ParameterSet(größe)
Ende Sub
Ende Klasse
<Serializable()> Öffentlich Klasse AttentionParameters
<JsonProperty()> Öffentlich Wq, Wk, Wv, Wo Als LayerParameters
Öffentliches Sub Neu(ByVal hDim Als Ganzzahl)
Wq = Neue LayerParameters(hDim, hDim) : Wk = Neue LayerParameters(hDim, hDim)
Wv = Neue LayerParameters(hDim, hDim) : Wo = Neue LayerParameters(hDim, hDim)
Ende Sub
Ende Klasse
<Serializable()> Öffentlich Klasse FFNParameters
<JsonProperty()> Öffentlich Layer1, Layer2 Als LayerParameters
Öffentliches Sub Neu(ByVal hDim Als Ganzzahl)
Layer1 = Neue LayerParameters(ffnDim, hDim)
Layer2 = Neue LayerParameters(hDim, ffnDim)
Ende Sub
Ende Klasse
<Serializable()> Öffentlich Klasse TransformerBlockParameters
<JsonProperty()> Öffentlich SelfAttention Als AttentionParameters
<JsonProperty()> Öffentlich FeedForward Als FFNParameters
<JsonProperty()> Öffentlich LN1, LN2 Als LayerNormParameters
Öffentliches Sub Neu(ByVal hDim Als Ganzzahl, ByVal ffnDim Als Ganzzahl)
SelfAttention = Neue AttentionParameters(hDim)
FeedForward = Neue FFNParameters(hDim, ffnDim)
LN1 = Neue LayerNormParameters(hDim) : LN2 = Neue LayerNormParameters(hDim)
Ende Sub
Ende Klasse
<JsonProperty()> Privat TokenEmbeddings Als ParameterSet
<JsonProperty()> Privat PositionalEmbeddings Als ParameterSet
<JsonProperty()> Privat TransformerBlocks Als Liste(Of TransformerBlockParameters)
<JsonProperty()> Privat FinalLayerNorm Als LayerNormParameters
<JsonProperty()> Privat LM_Head Als LayerParameters
<JsonProperty()> Privat adam_t Als Längere Zahl = 0
<NonSerialized()> Privat rnd Als Zufallszahl
<NonSerialized()> Öffentlich isTraining Als Boolean = Falsch
#End Region
#Region "Vorwärtsdurchgang und Cache-Strukturen"
Öffentlich Klasse LN_Cache_Matrix
Öffentlich X_hat Als Einzel()
Öffentlich StdDev Als Einzel()
Ende Klasse
Öffentlich Klasse FFN_Cache_Matrix
Öffentliches Eingangs Als Einzel()
Öffentlich Net1, Activated1 Als Einzel()
Ende Klasse
Öffentlich Klasse MHA_Cache_Matrix
Öffentlich Eingangs Als Einzel()
Öffentlich Q_proj, K_proj, V_proj Als Einzel()
Öffentlich AttnWeights Als Einzel()
Öffentliches ConcatOutput Als Einzel()
Ende Klasse
Öffentlich Klasse TransformerBlockCache_Matrix
Öffentlich Eingangs Als Einzel()
Öffentlich LN1_Cache Als Neue LN_Cache_Matrix(), LN2_Cache Als Neue LN_Cache_Matrix()
Öffentliches Gemeinsames Sub GeLUGradMatrix(ByVal grad_output() Als Einzel, ByVal net_input() Als Einzel, ByVal grad_input() Als Einzel, ByVal nElements Als Ganzzahl)
Öffentliches DropoutMask_Attn Als Boolean(), DropoutMask_FFN Als Boolean()
Ende Klasse
Öffentlich Klasse ForwardPassResult_Matrix
Öffentlich Logits Als Einzel()
Öffentlich BlockCaches Als Liste(Of TransformerBlockCache_Matrix)
Öffentlich FinalHiddenStates Als Einzel()
Öffentliches FinalLNCache Als Neue LN_Cache_Matrix()
Ende Klasse
#End Region
#Region "Vorhersage und Generierung (Mit Top-P Sampling)"
Öffentlich Klasse OptimizedKVCache
Öffentlich K Als Liste(Of Einzel())
Öffentlich V Als Liste(Of Einzel())
Öffentliches Sub Neu()
K = Neue Liste(Of Einzel())()
V = Neue Liste(Of Einzel())()
Ende Sub
Öffentliches Sub Add(ByVal newK Als Einzel(), ByVal newV Als Einzel())
K.Add(CType(neueK.Clone(), Einzel()))
V.Add(CType(neueV.Clone(), Einzel()))
Ende Sub
Ende Klasse
Öffentlich Funktion Predecir(ByVal prompt_ids Als Liste(Of Ganzzahl), Optional ByVal maxNewTokens Als Ganzzahl = 50, Optional ByVal temperature Als Einzel = 0.8F, Optional ByVal topK Als Ganzzahl = 40, Optional ByVal topP Als Einzel = 0.95F, Optional ByVal stopTokenId Als Ganzzahl = -1, Optional ByVal repetitionPenalty Als Einzel = 1.0F) Als Liste(Of Ganzzahl)
Wenn prompt_ids Ist Nichts Oder prompt_ids.Count = 0 Dann Rückgabe Neue Liste(Of Ganzzahl)()
isTraining = Falsch
Dim generated_ids = Neue Liste(Of Ganzzahl)(prompt_ids)
Dim kv_cache Als Neue Liste(Of OptimizedKVCache)
Für i = 0 Bis nLayers - 1 : kv_cache.Add(Neue OptimizedKVCache()) : Nächster
Dim hidden_state Als Einzel() = ProcessPromptAndPopulateCache(prompt_ids, kv_cache)
Für newTokenIndex Als Ganzzahl = 0 Bis maxNewTokens - 1
Wenn generated_ids.Count >= maxSeqLen Dann Beenden Für
Dim logits = GetLogitsFromState(hidden_state)
Dim next_token_id = GetNextToken(logits, generated_ids, temperature, topK, topP, repetitionPenalty)
Wenn stopTokenId > -1 Und next_token_id = stopTokenId Dann Beenden Für
generated_ids.Add(next_token_id)
hidden_state = ProcessSingleTokenAndUpdateCache(next_token_id, generated_ids.Count - 1, kv_cache)
Nächster
Rückgabe generated_ids
Ende Funktion
Privat Funktion ProcessPromptAndPopulateCache(ByVal prompt_ids Als Liste(Of Ganzzahl), ByVal kv_cache Als Liste(Of OptimizedKVCache)) Als Einzel()
Dim current_hidden_state Als Einzel() = Nichts
Für pos = 0 Bis prompt_ids.Count - 1
current_hidden_state = ProcessSingleTokenAndUpdateCache(prompt_ids(pos), pos, kv_cache)
Nächster
Rückgabe current_hidden_state
Ende Funktion
Privat Funktion ProcessSingleTokenAndUpdateCache(ByVal token_id Als Ganzzahl, ByVal position Als Ganzzahl, ByVal kv_cache Als Liste(Of OptimizedKVCache)) Als Einzel()
Dim hidden_state(hiddenDim - 1) Als Einzel
Array.Copy(TokenEmbeddings.W, token_id * hiddenDim, hidden_state, 0, hiddenDim)
Wenn position < maxSeqLen Dann
Dim pos_offset = position * hiddenDim
Für i = 0 Bis hidden_state.Länge - 1
hidden_state(i) += PositionalEmbeddings.W(pos_offset + i)
Nächster
Ende Wenn
Für layer_idx = 0 Bis nLayers - 1
Dim block_params = TransformerBlocks(layer_idx)
Dim ln1_out(hiddenDim - 1) Als Einzel
MatematicasOptimizadas.LayerNormMatrix(hidden_state, block_params.LN1.Gamma.W, block_params.LN1.Beta.W, ln1_out, 1, hiddenDim)
Dim attn_output = MultiHeadAttention_With_Cache(ln1_out, layer_idx, kv_cache(layer_idx))
AddMatrices(hidden_state, attn_output)
Dim ln2_out(hiddenDim - 1) Als Einzel
MatematicasOptimizadas.LayerNormMatrix(hidden_state, block_params.LN2.Gamma.W, block_params.LN2.Beta.W, ln2_out, 1, hiddenDim)
Dim ffn_output = FeedForward_Forward_Matrix(ln2_out, block_params.FeedForward, Neue FFN_Cache_Matrix(), 1)
AddMatrices(hidden_state, ffn_output)
Nächster
Rückgabe hidden_state
Ende Funktion
Privat Funktion FeedForward_Forward_Matrix(ByVal x() Als Einzel, ByVal params Als FFNParameters, ByVal cache Als FFN_Cache_Matrix, ByVal seqLen Als Ganzzahl) Als Einzel()
Dim hidden(seqLen * ffnHiddenDim - 1) Als Einzel
MatematicasOptimizadas.MultiplicarMatrizMatriz(x, params.Layer1.Weights.W, hidden, seqLen, hiddenDim, ffnHiddenDim)
AddVectorToMatrixRowsSafe(hidden, seqLen, ffnHiddenDim, params.Layer1.Biases.W)
MatematicasOptimizadas.GeLUMatrix(hidden, hidden.Length)
Dim output(seqLen * hiddenDim - 1) Als Einzel
MatematicasOptimizadas.MultiplicarMatrizMatriz(hidden, params.Layer2.Weights.W, output, seqLen, ffnHiddenDim, hiddenDim)
AddVectorToMatrixRowsSafe(output, seqLen, hiddenDim, params.Layer2.Biases.W)
Rückgabe Ausgabe
Ende Funktion
Privat Funktion MultiHeadAttention_With_Cache(ByVal q_input Als Einzel(), ByVal layer_idx Als Ganzzahl, ByVal current_layer_cache Als OptimizedKVCache) Als Einzel()
Dim params = TransformerBlocks(layer_idx).SelfAttention
Dim q_proj(hiddenDim - 1) Als Einzel : MatematicasOptimizadas.MultiplicarMatrizMatriz(q_input, params.Wq.Weights.W, q_proj, 1, hiddenDim, hiddenDim) : AddVectorToMatrixRowsSafe(q_proj, 1, hiddenDim, params.Wq.Biases.W)
Dim k_proj(hiddenDim - 1) Als Einzel : MatematicasOptimizadas.MultiplicarMatrizMatriz(q_input, params.Wk.Weights.W, k_proj, 1, hiddenDim, hiddenDim) : AddVectorToMatrixRowsSafe(k_proj, 1, hiddenDim, params.Wk.Biases.W)
Dim v_proj(hiddenDim - 1) Als Einzel : MatematicasOptimizadas.MultiplicarMatrizMatriz(q_input, params.Wv.Weights.W, v_proj, 1, hiddenDim, hiddenDim) : AddVectorToMatrixRowsSafe(v_proj, 1, hiddenDim, params.Wv.Biases.W)
current_layer_cache.Add(k_proj, v_proj)
Dim concat_output(hiddenDim - 1) Als Einzel
Dim scale = CSng(Math.Sqrt(headDim))
Parallel.For(0, nHeads, Sub(h)
Dim headOffset = h * headDim
Dim head_q(headDim - 1) Als Einzel : Array.Copy(q_proj, headOffset, head_q, 0, headDim)
Dim scores(current_layer_cache.K.Count - 1) Als Einzel
Für i = 0 Bis current_layer_cache.K.Count - 1
Dim head_k(headDim - 1) Als Einzel
Array.Copy(current_layer_cache.K(i), headOffset, head_k, 0, headDim)
Dim dotProd Als Einzel = 0.0F
Für d = 0 Bis headDim - 1 : dotProd += head_q(d) * head_k(d) : Nächster
scores(i) = dotProd / scale
Nächster
Dim attn_weights(scores.Length - 1) Als Einzel
MatematicasOptimizadas.StableSoftmaxMatrix(scores, attn_weights, 1, scores.Länge)
Dim head_output(headDim - 1) Als Einzel
Für i = 0 Bis current_layer_cache.V.Count - 1
Dim head_v(headDim - 1) Als Einzel
Array.Copy(current_layer_cache.V(i), headOffset, head_v, 0, headDim)
Für d = 0 Bis headDim - 1 : head_output(d) += attn_weights(i) * head_v(d) : Nächster
Nächster
Array.Copy(head_output, 0, concat_output, headOffset, headDim)
Ende Sub)
Dim final_output(hiddenDim - 1) Als Einzel
MatematicasOptimizadas.MultiplicarMatrizMatriz(concat_output, params.Wo.Weights.W, final_output, 1, hiddenDim, hiddenDim)
AddVectorToMatrixRowsSafe(final_output, 1, hiddenDim, params.Wo.Biases.W)
Rückgabe final_output
Ende Funktion
Privat Sub AddVectorToMatrixRowsSafe(ByVal matrix() Als Einzel, ByVal rows Als Ganzzahl, ByVal cols Als Ganzzahl, ByVal bias() Als Einzel)
Für i Als Ganzzahl = 0 Bis zeilen - 1
Dim baseIdx Als Ganzzahl = i * cols
Für j Als Ganzzahl = 0 Bis cols - 1
matrix(baseIdx + j) += bias(j)
Nächster
Nächster
Ende Sub
Privat Funktion GetLogitsFromState(ByVal hidden_state Als Einzel()) Als Einzel()
Dim final_norm_out(hiddenDim - 1) Als Einzel
MatematicasOptimizadas.LayerNormMatrix(hidden_state, FinalLayerNorm.Gamma.W, FinalLayerNorm.Beta.W, final_norm_out, 1, hiddenDim)
Dim logits(vocabSize - 1) Als Einzel
MatematicasOptimizadas.MultiplicarMatrizMatrizT2(final_norm_out, LM_Head.Weights.W, logits, 1, hiddenDim, vocabSize)
Rückgabe logits
Ende Funktion
Privat Funktion GetNextToken(ByVal logits Als Einzel(), ByVal generatedTokens Als Liste(Of Ganzzahl), ByVal temperature Als Einzel, ByVal topK Als Ganzzahl, ByVal topP Als Einzel, ByVal repetitionPenalty Als Einzel) Als Ganzzahl
Wenn repetitionPenalty > 1.0F Und generatedTokens Ist Nicht Nichts Und generatedTokens.Count > 0 Dann
Dim uniqueTokens = Neue HashSet(Of Ganzzahl)(generatedTokens)
Für Jede tokenId In uniqueTokens
Wenn tokenId < logits.Länge Dann logits(tokenId) = Wenn(logits(tokenId) > 0, logits(tokenId) / repetitionPenalty, logits(tokenId) * repetitionPenalty)
Nächster
Ende Wenn
Wenn temperature > 0.000001F Dann
Für i Als Ganzzahl = 0 Bis logits.Länge - 1 : logits(i) /= temperature : Nächster
Ende Wenn
Wenn topK > 0 Und topK < logits.Länge Dann
Dim indexedLogits = logits.Select(Function(logit, idx) Neues Mit {.Wert = logit, .Index = idx}).ToList()
Dim topKIndices = Neue HashSet(Of Ganzzahl)(indexedLogits.OrderByDescending(Funktion(x) x.Wert).Nehmen(topK).Wählen(Funktion(x) x.Index))
Für i Als Ganzzahl = 0 Bis logits.Länge - 1
Wenn Not topKIndices.Contains(i) Dann logits(i) = Einzel.NegativeInfinity
Nächster
Ende Wenn
' --- TOP-P SAMPLING (Nucleus Sampling) ---
Wenn topP > 0.0F Und topP < 1.0F Dann
Dim tempProbs(logits.Länge - 1) Als Einzel
MatematicasOptimizadas.StableSoftmaxMatrix(logits, tempProbs, 1, logits.Länge)
Dim indexedProbs = tempProbs.Select(Function(prob, idx) Neues Mit {.Prob = prob, .Index = idx}).OrderByDescending(Function(x) x.Prob).ToList()
Dim cumulative Als Einzel = 0.0F
Dim topPIndices Als Neue HashSet(Of Ganzzahl)()
Für Jede item In indexedProbs
topPIndices.Add(item.Index)
cumulative += item.Prob
Wenn cumulative >= topP Dann Beenden Für
Nächster
Für i Als Ganzzahl = 0 Bis logits.Länge - 1
Wenn Not topPIndices.Contains(i) Dann logits(i) = Einzel.NegativeInfinity
Nächster
Ende Wenn
Dim probs(logits.Länge - 1) Als Einzel
MatematicasOptimizadas.StableSoftmaxMatrix(logits, probs, 1, logits.Länge)
Rückgabe Wenn(temperature <= 0.01F, Array.IndexOf(probs, probs.Max()), GetSampledToken(probs))
Ende Funktion
Privat Funktion GetSampledToken(ByVal probs Als Einzel()) Als Ganzzahl
Dim randVal Als Einzel
SyncLock rnd : randVal = CSng(rnd.NextDouble()) : Ende SyncLock
Dim cumulative = 0.0F
Für i Als Ganzzahl = 0 Bis probs.Länge - 1
cumulative += probs(i)
Wenn randVal <= cumulative Dann Rückgabe i
Nächster
Rückgabe probs.Länge - 1
Ende Funktion
#End Region
Ende Klasse
