|
|
|
|
@ -17,6 +17,7 @@ const SHADER_SOFTMAX_NORM = fs.readFileSync('shader/softmaxnorm.wgsl').toString( |
|
|
|
|
const SHADER_DLDO = fs.readFileSync('shader/dldo.wgsl').toString(); |
|
|
|
|
const SHADER_SOFTMAX_GRAD = fs.readFileSync('shader/softmaxgrad.wgsl').toString(); |
|
|
|
|
const SHADER_LAYERNORM_GRAD = fs.readFileSync('shader/layernormgrad.wgsl').toString(); |
|
|
|
|
const SHADER_CLIP = fs.readFileSync('shader/clip.wgsl').toString(); |
|
|
|
|
const SHADER_ARGMAX = fs.readFileSync('shader/argmax.wgsl').toString(); |
|
|
|
|
const SHADER_SAMPLES = fs.readFileSync('shader/samples.wgsl').toString(); |
|
|
|
|
|
|
|
|
|
@ -40,7 +41,7 @@ export interface ModelData< |
|
|
|
|
> extends ModelInitData<V, W, D> { |
|
|
|
|
stage: 'early' | 'mid' | 'end'; |
|
|
|
|
tokenizer: string; |
|
|
|
|
samples: number; |
|
|
|
|
step: number; |
|
|
|
|
weights: { |
|
|
|
|
inp: CPUMatrix<V, D>; |
|
|
|
|
pos: CPUMatrix<W, D>; |
|
|
|
|
@ -49,6 +50,22 @@ export interface ModelData< |
|
|
|
|
tval: CPUMatrix<D, D>; |
|
|
|
|
out: CPUMatrix<V, D>; |
|
|
|
|
}; |
|
|
|
|
momentums: { |
|
|
|
|
inp: CPUMatrix<V, D>; |
|
|
|
|
pos: CPUMatrix<W, D>; |
|
|
|
|
tqry: CPUMatrix<D, D>; |
|
|
|
|
tkey: CPUMatrix<D, D>; |
|
|
|
|
tval: CPUMatrix<D, D>; |
|
|
|
|
out: CPUMatrix<V, D>; |
|
|
|
|
}; |
|
|
|
|
velocities: { |
|
|
|
|
inp: CPUMatrix<V, D>; |
|
|
|
|
pos: CPUMatrix<W, D>; |
|
|
|
|
tqry: CPUMatrix<D, D>; |
|
|
|
|
tkey: CPUMatrix<D, D>; |
|
|
|
|
tval: CPUMatrix<D, D>; |
|
|
|
|
out: CPUMatrix<V, D>; |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
interface TrainingPoint { |
|
|
|
|
@ -109,7 +126,7 @@ export class Model< |
|
|
|
|
public readonly ws: W; |
|
|
|
|
public readonly ds: D; |
|
|
|
|
|
|
|
|
|
protected samples: number = 0; |
|
|
|
|
protected step: number = 0; |
|
|
|
|
protected stage: 'early' | 'mid' | 'end' = 'early'; |
|
|
|
|
|
|
|
|
|
protected readonly weights: { |
|
|
|
|
@ -121,14 +138,41 @@ export class Model< |
|
|
|
|
readonly tout: Matrix<V, D, Float32Array>; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
protected readonly momentums: { |
|
|
|
|
readonly inp: Matrix<V, D, Float32Array>; |
|
|
|
|
readonly pos: Matrix<W, D, Float32Array>; |
|
|
|
|
readonly tqry: Matrix<D, D, Float32Array>; |
|
|
|
|
readonly tkey: Matrix<D, D, Float32Array>; |
|
|
|
|
readonly tval: Matrix<D, D, Float32Array>; |
|
|
|
|
readonly tout: Matrix<V, D, Float32Array>; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
protected readonly velocities: { |
|
|
|
|
readonly inp: Matrix<V, D, Float32Array>; |
|
|
|
|
readonly pos: Matrix<W, D, Float32Array>; |
|
|
|
|
readonly tqry: Matrix<D, D, Float32Array>; |
|
|
|
|
readonly tkey: Matrix<D, D, Float32Array>; |
|
|
|
|
readonly tval: Matrix<D, D, Float32Array>; |
|
|
|
|
readonly tout: Matrix<V, D, Float32Array>; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
protected readonly processing: { |
|
|
|
|
readonly one: Scalar<Float32Array>; |
|
|
|
|
readonly ds: Scalar<Float32Array>; |
|
|
|
|
readonly vs: Scalar<Float32Array>; |
|
|
|
|
readonly lr: Scalar<Float32Array>; |
|
|
|
|
readonly mbeta: Scalar<Float32Array>; |
|
|
|
|
readonly vbeta: Scalar<Float32Array>; |
|
|
|
|
readonly step: Scalar<Float32Array>; |
|
|
|
|
readonly thresholdL: Scalar<Float32Array>; |
|
|
|
|
readonly thresholdM: Scalar<Float32Array>; |
|
|
|
|
readonly thresholdS: Scalar<Float32Array>; |
|
|
|
|
readonly itids: Vector<W, Int32Array, TID>; |
|
|
|
|
readonly ilogits: Matrix<W, V, Float32Array>; |
|
|
|
|
readonly e: Matrix<W, D, Float32Array>; |
|
|
|
|
readonly ce: Matrix<W, D, Float32Array>; |
|
|
|
|
readonly ne: Matrix<W, D, Float32Array>; |
|
|
|
|
readonly tne: Matrix<D, W, Float32Array>; |
|
|
|
|
readonly q: Matrix<W, D, Float32Array>; |
|
|
|
|
readonly k: Matrix<W, D, Float32Array>; |
|
|
|
|
readonly qtk: Matrix<W, W, Float32Array>; |
|
|
|
|
@ -144,16 +188,27 @@ export class Model< |
|
|
|
|
readonly on: Matrix<W, V, Float32Array>; |
|
|
|
|
readonly ologits: Matrix<W, V, Float32Array>; |
|
|
|
|
readonly dldo: Matrix<W, V, Float32Array>; |
|
|
|
|
readonly dlda: Matrix<W, D, Float32Array>; |
|
|
|
|
readonly otdldo: Matrix<D, W, Float32Array>; |
|
|
|
|
readonly totdldowa: Matrix<W, D, Float32Array>; |
|
|
|
|
readonly dldv: Matrix<W, D, Float32Array>; |
|
|
|
|
readonly dlds: Matrix<W, W, Float32Array>; |
|
|
|
|
readonly dldsk: Matrix<W, D, Float32Array>; |
|
|
|
|
readonly dldsq: Matrix<W, D, Float32Array>; |
|
|
|
|
readonly ginp: Matrix<V, D, Float32Array>; |
|
|
|
|
readonly ginpnormh: Vector<V, Float32Array>; |
|
|
|
|
readonly ginpnorm: Scalar<Float32Array>; |
|
|
|
|
readonly gtqry: Matrix<D, D, Float32Array>; |
|
|
|
|
readonly gtqrynormh: Vector<D, Float32Array>; |
|
|
|
|
readonly gtqrynorm: Scalar<Float32Array>; |
|
|
|
|
readonly gtkey: Matrix<D, D, Float32Array>; |
|
|
|
|
readonly gtkeynormh: Vector<D, Float32Array>; |
|
|
|
|
readonly gtkeynorm: Scalar<Float32Array>; |
|
|
|
|
readonly gtval: Matrix<D, D, Float32Array>; |
|
|
|
|
readonly gtvalnormh: Vector<D, Float32Array>; |
|
|
|
|
readonly gtvalnorm: Scalar<Float32Array>; |
|
|
|
|
readonly gtout: Matrix<V, D, Float32Array>; |
|
|
|
|
readonly gtoutnormh: Vector<V, Float32Array>; |
|
|
|
|
readonly gtoutnorm: Scalar<Float32Array>; |
|
|
|
|
readonly rnd: Vector<W, Float32Array>; |
|
|
|
|
readonly otids: Vector<W, Int32Array, TID>; |
|
|
|
|
readonly ttids: Vector<W, Int32Array, TID>; |
|
|
|
|
@ -161,7 +216,8 @@ export class Model< |
|
|
|
|
|
|
|
|
|
protected async log<A extends Uint32Array | Int32Array | Float32Array>(name: string, s: GPUStruct<A>, sample: number = 4): Promise<void> { |
|
|
|
|
if (LOGGING) { |
|
|
|
|
console.log(name, (await s.get() as number[]).slice(0, sample)); |
|
|
|
|
const v = await s.get() as number[]; |
|
|
|
|
console.log(name, Array.isArray(v) ? v.slice(0, sample) : v); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -247,32 +303,39 @@ export class Model< |
|
|
|
|
return this.processing.v; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected s( |
|
|
|
|
protected async s( |
|
|
|
|
q: Matrix<W, D, Float32Array> = this.processing.q, |
|
|
|
|
k: Matrix<W, D, Float32Array> = this.processing.k, |
|
|
|
|
): Matrix<W, W, Float32Array> { |
|
|
|
|
Matrix.tmul(q, k, this.processing.qtk); |
|
|
|
|
): Promise<Matrix<W, W, Float32Array>> { |
|
|
|
|
Matrix.transrmul(q, k, this.processing.qtk); |
|
|
|
|
Matrix.scale(this.processing.ds, this.processing.qtk, this.processing.s); |
|
|
|
|
await this.log('s', this.processing.s); |
|
|
|
|
return this.processing.s; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected async wa(s: Matrix<W, W, Float32Array> = this.processing.s): Promise<Matrix<W, W, Float32Array>> { |
|
|
|
|
this.softmax(s, this.processing.se, this.processing.wa); |
|
|
|
|
await this.log('se', this.processing.se); |
|
|
|
|
await this.log('wa', this.processing.wa); |
|
|
|
|
return this.processing.wa; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected a( |
|
|
|
|
protected async a( |
|
|
|
|
e: Matrix<W, D, Float32Array> = this.processing.e, |
|
|
|
|
wa: Matrix<W, W, Float32Array> = this.processing.wa, |
|
|
|
|
v: Matrix<W, D, Float32Array> = this.processing.v, |
|
|
|
|
): Matrix<W, D, Float32Array> { |
|
|
|
|
): Promise<Matrix<W, D, Float32Array>> { |
|
|
|
|
Matrix.mul(wa, v, this.processing.ar); |
|
|
|
|
Matrix.sum(e, this.processing.ar, this.processing.a); |
|
|
|
|
await this.log('ar', this.processing.ar); |
|
|
|
|
await this.log('a', this.processing.a); |
|
|
|
|
return this.processing.a; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected o(a: Matrix<W, D, Float32Array> = this.processing.a): Matrix<W, V, Float32Array> { |
|
|
|
|
protected async o(a: Matrix<W, D, Float32Array> = this.processing.a): Promise<Matrix<W, V, Float32Array>> { |
|
|
|
|
this.processing.o.calculate('tout', SHADER_TWEIGH, [a, this.weights.tout]); |
|
|
|
|
await this.log('tout', this.weights.tout); |
|
|
|
|
await this.log('o', this.processing.o); |
|
|
|
|
return this.processing.o; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -307,6 +370,38 @@ export class Model< |
|
|
|
|
return probs.reduce((l: number, ps: CPUVector<V>, i: number) => l - Math.log(ps[target[i]] + 1e-10), 0) / probs.length; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected async adm<H extends number, W extends number>( |
|
|
|
|
step: number, |
|
|
|
|
m: Matrix<H, W, Float32Array>, |
|
|
|
|
v: Matrix<H, W, Float32Array>, |
|
|
|
|
g: Matrix<H, W, Float32Array>, |
|
|
|
|
): Promise<Matrix<H, W, Float32Array>> { |
|
|
|
|
await this.processing.step.set(step); |
|
|
|
|
|
|
|
|
|
Matrix.sum( |
|
|
|
|
Matrix.scale(this.processing.mbeta, m), |
|
|
|
|
Matrix.scale(Scalar.sub(this.processing.one, this.processing.mbeta), g), |
|
|
|
|
m, |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
Matrix.sum( |
|
|
|
|
Matrix.scale(this.processing.vbeta, v), |
|
|
|
|
Matrix.scale(Scalar.sub(this.processing.one, this.processing.vbeta), Matrix.esqr(g)), |
|
|
|
|
v, |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
const mhat = Matrix.scale(Scalar.div(this.processing.one, Scalar.sub(this.processing.one, Scalar.pow(this.processing.mbeta, this.processing.step))), m); |
|
|
|
|
const vhat = Matrix.scale(Scalar.div(this.processing.one, Scalar.sub(this.processing.one, Scalar.pow(this.processing.vbeta, this.processing.step))), v); |
|
|
|
|
|
|
|
|
|
Matrix.ediv( |
|
|
|
|
mhat, |
|
|
|
|
Matrix.sum(Matrix.esqrt(vhat), new Matrix(this.device, Float32Array, vhat.height, vhat.width, mat(vhat.height, vhat.width, () => 1e-8))), |
|
|
|
|
g, |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
return g; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected async upd( |
|
|
|
|
ilogits: Matrix<W, V, Float32Array> = this.processing.ilogits, |
|
|
|
|
ne: Matrix<W, D, Float32Array> = this.processing.ne, |
|
|
|
|
@ -324,77 +419,54 @@ export class Model< |
|
|
|
|
this.processing.dldo.calculate('dldo', SHADER_DLDO, [ |
|
|
|
|
ologits, |
|
|
|
|
ttids, |
|
|
|
|
this.processing.lr, |
|
|
|
|
this.processing.one, |
|
|
|
|
]); |
|
|
|
|
|
|
|
|
|
Matrix.mul(this.processing.dldo, this.weights.tout, this.processing.dlda); |
|
|
|
|
|
|
|
|
|
this.softmax_grad( |
|
|
|
|
wa, |
|
|
|
|
Matrix.mul(this.processing.dldo, Matrix.mul(this.weights.tout, Matrix.transpose(v))), |
|
|
|
|
Matrix.transrmul(this.processing.dlda, v), |
|
|
|
|
this.processing.dlds, |
|
|
|
|
); |
|
|
|
|
Matrix.scale(this.processing.ds, this.processing.dlds, this.processing.dlds); |
|
|
|
|
|
|
|
|
|
Matrix.translmul(this.processing.dlds, q, this.processing.dldsq); |
|
|
|
|
Matrix.mul(this.processing.dlds, k, this.processing.dldsk); |
|
|
|
|
Matrix.translmul(wa, this.processing.dlda, this.processing.dldv); |
|
|
|
|
Matrix.mul( |
|
|
|
|
Matrix.transpose(ilogits), |
|
|
|
|
Matrix.sum( |
|
|
|
|
Matrix.mul(this.processing.dldo, this.weights.tout), |
|
|
|
|
Matrix.scale(new Scalar(this.device, Float32Array, 0.5), this.processing.dlda), |
|
|
|
|
this.layernorm_grad( |
|
|
|
|
ne, |
|
|
|
|
Matrix.sum( |
|
|
|
|
Matrix.mul( |
|
|
|
|
Matrix.mul( |
|
|
|
|
this.processing.dlds, |
|
|
|
|
Matrix.scale(this.processing.ds, k), |
|
|
|
|
), |
|
|
|
|
this.weights.tqry, |
|
|
|
|
) |
|
|
|
|
, |
|
|
|
|
Matrix.sum( |
|
|
|
|
Matrix.mul( |
|
|
|
|
Matrix.mul( |
|
|
|
|
Matrix.transpose(this.processing.dlds), |
|
|
|
|
Matrix.scale(this.processing.ds, q), |
|
|
|
|
), |
|
|
|
|
this.weights.tkey, |
|
|
|
|
), |
|
|
|
|
Matrix.mul( |
|
|
|
|
Matrix.mul(Matrix.transpose(wa), this.processing.dldo), |
|
|
|
|
Matrix.mul(this.weights.tout, this.weights.tval), |
|
|
|
|
), |
|
|
|
|
), |
|
|
|
|
Matrix.sum3( |
|
|
|
|
Matrix.mul(this.processing.dldsk, this.weights.tqry), |
|
|
|
|
Matrix.mul(this.processing.dldsq, this.weights.tkey), |
|
|
|
|
Matrix.mul(this.processing.dldv, this.weights.tval), |
|
|
|
|
), |
|
|
|
|
), |
|
|
|
|
), |
|
|
|
|
this.processing.ginp, |
|
|
|
|
); |
|
|
|
|
await this.adm(this.step, this.momentums.inp, this.velocities.inp, this.processing.ginp); |
|
|
|
|
Matrix.scale(this.processing.lr, this.processing.ginp, this.processing.ginp); |
|
|
|
|
|
|
|
|
|
Matrix.transpose( |
|
|
|
|
Matrix.scale(this.processing.ds, Matrix.mul( |
|
|
|
|
Matrix.transpose(ne), |
|
|
|
|
Matrix.mul(this.processing.dlds, k), |
|
|
|
|
)), |
|
|
|
|
this.processing.gtqry, |
|
|
|
|
); |
|
|
|
|
Matrix.translmul(this.processing.dldsk, ne, this.processing.gtqry); |
|
|
|
|
await this.adm(this.step, this.momentums.tqry, this.velocities.tqry, this.processing.gtqry); |
|
|
|
|
Matrix.scale(this.processing.lr, this.processing.gtqry, this.processing.gtqry); |
|
|
|
|
|
|
|
|
|
Matrix.transpose( |
|
|
|
|
Matrix.scale(this.processing.ds, Matrix.mul( |
|
|
|
|
Matrix.transpose(ne), |
|
|
|
|
Matrix.mul(Matrix.transpose(this.processing.dlds), q), |
|
|
|
|
)), |
|
|
|
|
this.processing.gtkey, |
|
|
|
|
); |
|
|
|
|
Matrix.translmul(this.processing.dldsq, ne, this.processing.gtkey); |
|
|
|
|
await this.adm(this.step, this.momentums.tkey, this.velocities.tkey, this.processing.gtkey); |
|
|
|
|
Matrix.scale(this.processing.lr, this.processing.gtkey, this.processing.gtkey); |
|
|
|
|
|
|
|
|
|
Matrix.transpose( |
|
|
|
|
Matrix.mul( |
|
|
|
|
Matrix.mul(Matrix.transpose(ne), Matrix.transpose(wa)), |
|
|
|
|
Matrix.mul(this.processing.dldo, this.weights.tout), |
|
|
|
|
), |
|
|
|
|
this.processing.gtval, |
|
|
|
|
); |
|
|
|
|
Matrix.translmul(this.processing.dldv, ne, this.processing.gtval); |
|
|
|
|
await this.adm(this.step, this.momentums.tval, this.velocities.tval, this.processing.gtval); |
|
|
|
|
Matrix.scale(this.processing.lr, this.processing.gtval, this.processing.gtval); |
|
|
|
|
|
|
|
|
|
Matrix.transpose( |
|
|
|
|
Matrix.mul(Matrix.transpose(a), this.processing.dldo), |
|
|
|
|
this.processing.gtout, |
|
|
|
|
); |
|
|
|
|
Matrix.translmul(this.processing.dldo, a, this.processing.gtout); |
|
|
|
|
await this.adm(this.step, this.momentums.tout, this.velocities.tout, this.processing.gtout); |
|
|
|
|
Matrix.scale(this.processing.lr, this.processing.gtout, this.processing.gtout); |
|
|
|
|
|
|
|
|
|
Matrix.sum(this.processing.ginp, this.weights.inp, this.weights.inp); |
|
|
|
|
Matrix.sum(this.processing.gtqry, this.weights.tqry, this.weights.tqry); |
|
|
|
|
@ -423,7 +495,23 @@ export class Model< |
|
|
|
|
tqry: new Matrix(this.device, Float32Array, mat(this.ds, this.ds, () => (Math.random() - 0.5) * Math.sqrt(1 / this.ds))), |
|
|
|
|
tkey: new Matrix(this.device, Float32Array, mat(this.ds, this.ds, () => (Math.random() - 0.5) * Math.sqrt(1 / this.ds))), |
|
|
|
|
tval: new Matrix(this.device, Float32Array, mat(this.ds, this.ds, () => (Math.random() - 0.5) * Math.sqrt(1 / this.ds))), |
|
|
|
|
tout: new Matrix(this.device, Float32Array, mat(this.vs, this.ds, () => (Math.random() - 0.5) * Math.sqrt(1 / this.ds))), |
|
|
|
|
tout: new Matrix(this.device, Float32Array, mat(this.vs, this.ds, () => (Math.random() - 0.5) * Math.sqrt(1 / this.ds / this.vs))), |
|
|
|
|
}; |
|
|
|
|
this.momentums = { |
|
|
|
|
inp: new Matrix(this.device, Float32Array, mat(this.vs, this.ds, () => 0)), |
|
|
|
|
pos: new Matrix(this.device, Float32Array, mat(this.ws, this.ds, () => 0)), |
|
|
|
|
tqry: new Matrix(this.device, Float32Array, mat(this.ds, this.ds, () => 0)), |
|
|
|
|
tkey: new Matrix(this.device, Float32Array, mat(this.ds, this.ds, () => 0)), |
|
|
|
|
tval: new Matrix(this.device, Float32Array, mat(this.ds, this.ds, () => 0)), |
|
|
|
|
tout: new Matrix(this.device, Float32Array, mat(this.vs, this.ds, () => 0)), |
|
|
|
|
}; |
|
|
|
|
this.velocities = { |
|
|
|
|
inp: new Matrix(this.device, Float32Array, mat(this.vs, this.ds, () => 0)), |
|
|
|
|
pos: new Matrix(this.device, Float32Array, mat(this.ws, this.ds, () => 0)), |
|
|
|
|
tqry: new Matrix(this.device, Float32Array, mat(this.ds, this.ds, () => 0)), |
|
|
|
|
tkey: new Matrix(this.device, Float32Array, mat(this.ds, this.ds, () => 0)), |
|
|
|
|
tval: new Matrix(this.device, Float32Array, mat(this.ds, this.ds, () => 0)), |
|
|
|
|
tout: new Matrix(this.device, Float32Array, mat(this.vs, this.ds, () => 0)), |
|
|
|
|
}; |
|
|
|
|
} else { |
|
|
|
|
this.weights = { |
|
|
|
|
@ -434,21 +522,47 @@ export class Model< |
|
|
|
|
tval: new Matrix(this.device, Float32Array, data.weights.tval), |
|
|
|
|
tout: new Matrix(this.device, Float32Array, data.weights.out), |
|
|
|
|
}; |
|
|
|
|
this.momentums = { |
|
|
|
|
inp: new Matrix(this.device, Float32Array, data.momentums.inp), |
|
|
|
|
pos: new Matrix(this.device, Float32Array, data.momentums.pos), |
|
|
|
|
tqry: new Matrix(this.device, Float32Array, data.momentums.tqry), |
|
|
|
|
tkey: new Matrix(this.device, Float32Array, data.momentums.tkey), |
|
|
|
|
tval: new Matrix(this.device, Float32Array, data.momentums.tval), |
|
|
|
|
tout: new Matrix(this.device, Float32Array, data.momentums.out), |
|
|
|
|
}; |
|
|
|
|
this.velocities = { |
|
|
|
|
inp: new Matrix(this.device, Float32Array, data.velocities.inp), |
|
|
|
|
pos: new Matrix(this.device, Float32Array, data.velocities.pos), |
|
|
|
|
tqry: new Matrix(this.device, Float32Array, data.velocities.tqry), |
|
|
|
|
tkey: new Matrix(this.device, Float32Array, data.velocities.tkey), |
|
|
|
|
tval: new Matrix(this.device, Float32Array, data.velocities.tval), |
|
|
|
|
tout: new Matrix(this.device, Float32Array, data.velocities.out), |
|
|
|
|
}; |
|
|
|
|
this.stage = data.stage; |
|
|
|
|
this.samples = data.samples; |
|
|
|
|
this.step = data.step; |
|
|
|
|
if (data.tokenizer !== `${tokenizer.tokens.length}${tokenizer.tokens[0]}`) { |
|
|
|
|
throw new Error(`The model was trained against a different tokenizer ("${data.tokenizer}").`); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
this.processing = { |
|
|
|
|
one: new Scalar<Float32Array>(this.device, Float32Array, 1), |
|
|
|
|
ds: new Scalar<Float32Array>(this.device, Float32Array, 1 / Math.sqrt(this.ds)), |
|
|
|
|
vs: new Scalar<Float32Array>(this.device, Float32Array, 1 / Math.sqrt(this.vs)), |
|
|
|
|
lr: new Scalar<Float32Array>(this.device, Float32Array, 0), |
|
|
|
|
mbeta: new Scalar<Float32Array>(this.device, Float32Array, 0.9), |
|
|
|
|
vbeta: new Scalar<Float32Array>(this.device, Float32Array, 0.999), |
|
|
|
|
step: new Scalar<Float32Array>(this.device, Float32Array, 0), |
|
|
|
|
|
|
|
|
|
thresholdL: new Scalar<Float32Array>(this.device, Float32Array, 1e10), |
|
|
|
|
thresholdM: new Scalar<Float32Array>(this.device, Float32Array, 1e10), |
|
|
|
|
thresholdS: new Scalar<Float32Array>(this.device, Float32Array, 1e10), |
|
|
|
|
itids: new Vector<W, Int32Array, TID>(this.device, Int32Array, this.ws), |
|
|
|
|
ilogits: new Matrix<W, V, Float32Array>(this.device, Float32Array, this.ws, this.vs), |
|
|
|
|
e: new Matrix<W, D, Float32Array>(this.device, Float32Array, this.ws, this.ds), |
|
|
|
|
ce: new Matrix<W, D, Float32Array>(this.device, Float32Array, this.ws, this.ds), |
|
|
|
|
ne: new Matrix<W, D, Float32Array>(this.device, Float32Array, this.ws, this.ds), |
|
|
|
|
tne: new Matrix<D, W, Float32Array>(this.device, Float32Array, this.ds, this.ws), |
|
|
|
|
q: new Matrix<W, D, Float32Array>(this.device, Float32Array, this.ws, this.ds), |
|
|
|
|
k: new Matrix<W, D, Float32Array>(this.device, Float32Array, this.ws, this.ds), |
|
|
|
|
qtk: new Matrix<W, W, Float32Array>(this.device, Float32Array, this.ws, this.ws), |
|
|
|
|
@ -464,16 +578,27 @@ export class Model< |
|
|
|
|
on: new Matrix<W, V, Float32Array>(this.device, Float32Array, this.ws, this.vs), |
|
|
|
|
ologits: new Matrix<W, V, Float32Array>(this.device, Float32Array, this.ws, this.vs), |
|
|
|
|
dldo: new Matrix<W, V, Float32Array>(this.device, Float32Array, this.ws, this.vs), |
|
|
|
|
dlda: new Matrix<W, D, Float32Array>(this.device, Float32Array, this.ws, this.ds), |
|
|
|
|
otdldo: new Matrix<D, W, Float32Array>(this.device, Float32Array, this.ds, this.ws), |
|
|
|
|
totdldowa: new Matrix<W, D, Float32Array>(this.device, Float32Array, this.ws, this.ds), |
|
|
|
|
dldv: new Matrix<W, D, Float32Array>(this.device, Float32Array, this.ws, this.ds), |
|
|
|
|
dlds: new Matrix<W, W, Float32Array>(this.device, Float32Array, this.ws, this.ws), |
|
|
|
|
dldsk: new Matrix<W, D, Float32Array>(this.device, Float32Array, this.ws, this.ds), |
|
|
|
|
dldsq: new Matrix<W, D, Float32Array>(this.device, Float32Array, this.ws, this.ds), |
|
|
|
|
ginp: new Matrix(this.device, Float32Array, this.vs, this.ds), |
|
|
|
|
ginpnormh: new Vector(this.device, Float32Array, this.vs), |
|
|
|
|
ginpnorm: new Scalar(this.device, Float32Array), |
|
|
|
|
gtqry: new Matrix(this.device, Float32Array, this.ds, this.ds), |
|
|
|
|
gtqrynormh: new Vector(this.device, Float32Array, this.ds), |
|
|
|
|
gtqrynorm: new Scalar(this.device, Float32Array), |
|
|
|
|
gtkey: new Matrix(this.device, Float32Array, this.ds, this.ds), |
|
|
|
|
gtkeynormh: new Vector(this.device, Float32Array, this.ds), |
|
|
|
|
gtkeynorm: new Scalar(this.device, Float32Array), |
|
|
|
|
gtval: new Matrix(this.device, Float32Array, this.ds, this.ds), |
|
|
|
|
gtvalnormh: new Vector(this.device, Float32Array, this.ds), |
|
|
|
|
gtvalnorm: new Scalar(this.device, Float32Array), |
|
|
|
|
gtout: new Matrix(this.device, Float32Array, this.vs, this.ds), |
|
|
|
|
gtoutnormh: new Vector(this.device, Float32Array, this.vs), |
|
|
|
|
gtoutnorm: new Scalar(this.device, Float32Array), |
|
|
|
|
rnd: new Vector<W, Float32Array>(this.device, Float32Array, this.ws), |
|
|
|
|
otids: new Vector<W, Int32Array, TID>(this.device, Int32Array, this.ws), |
|
|
|
|
ttids: new Vector<W, Int32Array, TID>(this.device, Int32Array, this.ws), |
|
|
|
|
@ -560,7 +685,7 @@ export class Model< |
|
|
|
|
|
|
|
|
|
const seed = tids.slice(tids.length / 2, tids.length / 2 + 100); |
|
|
|
|
|
|
|
|
|
let lr = 0.003; |
|
|
|
|
const lr = 0.003; |
|
|
|
|
|
|
|
|
|
for (let epoch = 0; epoch < epochs; epoch++) { |
|
|
|
|
const idxs = randseq(tids.length); |
|
|
|
|
@ -577,10 +702,10 @@ export class Model< |
|
|
|
|
const q = await this.q(ne); |
|
|
|
|
const k = await this.k(ne); |
|
|
|
|
const v = await this.v(ne); |
|
|
|
|
const s = this.s(q, k); |
|
|
|
|
const s = await this.s(q, k); |
|
|
|
|
const wa = await this.wa(s); |
|
|
|
|
const a = this.a(e, wa, v); |
|
|
|
|
const o = this.o(a); |
|
|
|
|
const a = await this.a(e, wa, v); |
|
|
|
|
const o = await this.o(a); |
|
|
|
|
const ologits = await this.ologits(o); |
|
|
|
|
await this.upd(ilogits, ne, q, k, v, wa, a, ologits, this.processing.ttids, lr); |
|
|
|
|
|
|
|
|
|
@ -590,7 +715,7 @@ export class Model< |
|
|
|
|
|
|
|
|
|
const end: number = Date.now(); |
|
|
|
|
|
|
|
|
|
this.samples += 1; |
|
|
|
|
this.step += 1; |
|
|
|
|
times.push(end - begin); |
|
|
|
|
|
|
|
|
|
if ( |
|
|
|
|
@ -599,18 +724,18 @@ export class Model< |
|
|
|
|
|| end - logged > statsInterval |
|
|
|
|
) { |
|
|
|
|
const point: TrainingPoint = { |
|
|
|
|
index: this.samples, |
|
|
|
|
index: this.step, |
|
|
|
|
timestamp: Date.now(), |
|
|
|
|
epoch, |
|
|
|
|
batch, |
|
|
|
|
lr, |
|
|
|
|
loss: 0, |
|
|
|
|
accuracy: 0, |
|
|
|
|
ginp: (await this.processing.ginp.get()).reduce((s, r) => r.reduce((s, v) => s + v * v, s), 0) / lr / lr, |
|
|
|
|
gqry: (await this.processing.gtqry.get()).reduce((s, r) => r.reduce((s, v) => s + v * v, s), 0) / lr / lr, |
|
|
|
|
gkey: (await this.processing.gtkey.get()).reduce((s, r) => r.reduce((s, v) => s + v * v, s), 0) / lr / lr, |
|
|
|
|
gval: (await this.processing.gtval.get()).reduce((s, r) => r.reduce((s, v) => s + v * v, s), 0) / lr / lr, |
|
|
|
|
gout: (await this.processing.gtout.get()).reduce((s, r) => r.reduce((s, v) => s + v * v, s), 0) / lr / lr, |
|
|
|
|
ginp: await this.processing.ginpnorm.get(), |
|
|
|
|
gqry: await this.processing.gtqrynorm.get(), |
|
|
|
|
gkey: await this.processing.gtkeynorm.get(), |
|
|
|
|
gval: await this.processing.gtvalnorm.get(), |
|
|
|
|
gout: await this.processing.gtoutnorm.get(), |
|
|
|
|
queueing: 0, |
|
|
|
|
computing: 0, |
|
|
|
|
inferring: 0, |
|
|
|
|
@ -631,27 +756,27 @@ export class Model< |
|
|
|
|
|
|
|
|
|
losses.push(point.loss); |
|
|
|
|
|
|
|
|
|
if (this.stage === 'early') { |
|
|
|
|
lr = Math.max(0.001, Math.min(0.003, point.loss * 0.001)); |
|
|
|
|
|
|
|
|
|
if (losses.length > aw && (slope(losses.slice(-aw)) > -0.005 || stddev(losses.slice(-aw)) < 0.2)) { |
|
|
|
|
logs?.write('Switching to mid stage.\n'); |
|
|
|
|
this.stage = 'mid'; |
|
|
|
|
} |
|
|
|
|
} else if (this.stage === 'mid') { |
|
|
|
|
lr = Math.max(0.0003, lr * 0.98); |
|
|
|
|
|
|
|
|
|
if (losses.length > aw && Math.abs(slope(losses.slice(-aw))) < 0.002 && stddev(losses.slice(-aw)) < 0.05) { |
|
|
|
|
logs?.write('Switching to end stage.\n'); |
|
|
|
|
this.stage = 'end'; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
lr = Math.max(1e-4, lr * 0.98); |
|
|
|
|
} |
|
|
|
|
// if (this.stage === 'early') {
|
|
|
|
|
// lr = Math.max(0.001, Math.min(0.003, point.loss * 0.001));
|
|
|
|
|
|
|
|
|
|
// if (losses.length > aw && (slope(losses.slice(-aw)) > -0.005 || stddev(losses.slice(-aw)) < 0.2)) {
|
|
|
|
|
// logs?.write('Switching to mid stage.\n');
|
|
|
|
|
// this.stage = 'mid';
|
|
|
|
|
// }
|
|
|
|
|
// } else if (this.stage === 'mid') {
|
|
|
|
|
// lr = Math.max(0.0003, lr * 0.98);
|
|
|
|
|
|
|
|
|
|
// if (losses.length > aw && Math.abs(slope(losses.slice(-aw))) < 0.002 && stddev(losses.slice(-aw)) < 0.05) {
|
|
|
|
|
// logs?.write('Switching to end stage.\n');
|
|
|
|
|
// this.stage = 'end';
|
|
|
|
|
// }
|
|
|
|
|
// } else {
|
|
|
|
|
// lr = Math.max(1e-4, lr * 0.98);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
logs?.write(`Done ${epoch * batches + batch + 1} / ${epochs * batches}, ETA ${Math.round(drm(times) * (epochs * batches - times.length) / 1000)}s\n`); |
|
|
|
|
stats?.write(`${Object.values(point).join(',')}\n`); |
|
|
|
|
await this.debug(this.samples, this.processing.itids, this.processing.ttids, o, ologits, logits); |
|
|
|
|
await this.debug(this.step, this.processing.itids, this.processing.ttids, o, ologits, logits); |
|
|
|
|
|
|
|
|
|
logged = end; |
|
|
|
|
} |
|
|
|
|
@ -713,10 +838,10 @@ export class Model< |
|
|
|
|
const q = await this.q(ne); |
|
|
|
|
const k = await this.k(ne); |
|
|
|
|
const v = await this.v(ne); |
|
|
|
|
const s = this.s(q, k); |
|
|
|
|
const s = await this.s(q, k); |
|
|
|
|
const wa = await this.wa(s); |
|
|
|
|
const a = this.a(e, wa, v); |
|
|
|
|
const o = this.o(a); |
|
|
|
|
const a = await this.a(e, wa, v); |
|
|
|
|
const o = await this.o(a); |
|
|
|
|
const ologits = await this.ologits(o, temp === 'max' ? 1 : temp); |
|
|
|
|
const out = temp === 'max' ? this.otids(ologits) : this.otids(await this.rnd(), ologits); |
|
|
|
|
const otids = await out.get(); |
|
|
|
|
@ -752,7 +877,7 @@ export class Model< |
|
|
|
|
ws: this.ws, |
|
|
|
|
ds: this.ds, |
|
|
|
|
stage: this.stage, |
|
|
|
|
samples: this.samples, |
|
|
|
|
step: this.step, |
|
|
|
|
weights: { |
|
|
|
|
inp: await this.weights.inp.get(), |
|
|
|
|
pos: await this.weights.pos.get(), |
|
|
|
|
@ -761,6 +886,22 @@ export class Model< |
|
|
|
|
tval: await this.weights.tval.get(), |
|
|
|
|
out: await this.weights.tout.get(), |
|
|
|
|
}, |
|
|
|
|
momentums: { |
|
|
|
|
inp: await this.momentums.inp.get(), |
|
|
|
|
pos: await this.momentums.pos.get(), |
|
|
|
|
tqry: await this.momentums.tqry.get(), |
|
|
|
|
tkey: await this.momentums.tkey.get(), |
|
|
|
|
tval: await this.momentums.tval.get(), |
|
|
|
|
out: await this.momentums.tout.get(), |
|
|
|
|
}, |
|
|
|
|
velocities: { |
|
|
|
|
inp: await this.velocities.inp.get(), |
|
|
|
|
pos: await this.velocities.pos.get(), |
|
|
|
|
tqry: await this.velocities.tqry.get(), |
|
|
|
|
tkey: await this.velocities.tkey.get(), |
|
|
|
|
tval: await this.velocities.tval.get(), |
|
|
|
|
out: await this.velocities.tout.get(), |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|