Download runtime/go/seqnet.go from Dibachain/DibaGuard: direct link, hf CLI and curl.
- Browser
- Download file 5.64 kB
-
https://huggingface.co/Dibachain/DibaGuard/resolve/main/runtime/go/seqnet.go
- Command line
-
hf download hf://Dibachain/DibaGuard/runtime/go/seqnet.go
-
curl -L -o seqnet.go https://huggingface.co/Dibachain/DibaGuard/resolve/main/runtime/go/seqnet.go
5.64 kB
| package dibaguard | |
| import ( | |
| "fmt" | |
| "math" | |
| ) | |
| // SeqNet is the tier-2 sequence network (dibaguard/flows/seqnet.py): event encoder -> causal GRU (one hidden | |
| // state per source, one step per flow) -> site-conditioned head. Weights come from the flat export of seqnet.npz. | |
| type SeqNet struct { | |
| EmbPort, EmbProto []float32 // [PortVocab*16], [ProtoVocab*4] | |
| Enc0W, Enc0B, Enc1W, Enc1B []float32 // [D*In], [D], [D*D], [D] | |
| WIH, WHH, BIH, BHH [][]float32 | |
| CtxW, CtxB []float32 // [2D*D], [2D] (nil without context) | |
| Head0W, Head0B []float32 // [64*D], [64] | |
| Head1W, Head1B []float32 // [C*64], [C] | |
| Gamma, Beta []float32 // [D] from the active site context | |
| D, In, Layers, C, NumIn int | |
| PortVocab, ProtoVocab int | |
| Temp float64 | |
| Info map[string]any | |
| } | |
| // LoadSeqNet reads a flat export of SeqNet and applies the shipped default context when present. | |
| func LoadSeqNet(path string) (*SeqNet, error) { | |
| f, err := LoadFlat(path) | |
| if err != nil { | |
| return nil, err | |
| } | |
| m := &SeqNet{Info: f.Info, Temp: 1} | |
| get := func(name string) ([]float32, []int) { | |
| if err != nil { | |
| return nil, nil | |
| } | |
| var a []float32 | |
| var s []int | |
| a, s, err = f.Float32s(name) | |
| return a, s | |
| } | |
| var shp []int | |
| m.EmbPort, shp = get("emb_port") | |
| if shp != nil { | |
| m.PortVocab = shp[0] | |
| } | |
| m.EmbProto, shp = get("emb_proto") | |
| if shp != nil { | |
| m.ProtoVocab = shp[0] | |
| } | |
| m.Enc0W, shp = get("enc.0.w") | |
| if shp != nil { | |
| m.D, m.In = shp[0], shp[1] | |
| m.NumIn = m.In - 20 | |
| } | |
| m.Enc0B, _ = get("enc.0.b") | |
| m.Enc1W, _ = get("enc.1.w") | |
| m.Enc1B, _ = get("enc.1.b") | |
| for l := 0; ; l++ { | |
| if _, ok := f.arrays[fmt.Sprintf("gru.l%d.w_hh", l)]; !ok { | |
| break | |
| } | |
| wih, _ := get(fmt.Sprintf("gru.l%d.w_ih", l)) | |
| whh, _ := get(fmt.Sprintf("gru.l%d.w_hh", l)) | |
| bih, _ := get(fmt.Sprintf("gru.l%d.b_ih", l)) | |
| bhh, _ := get(fmt.Sprintf("gru.l%d.b_hh", l)) | |
| m.WIH, m.WHH, m.BIH, m.BHH = append(m.WIH, wih), append(m.WHH, whh), append(m.BIH, bih), append(m.BHH, bhh) | |
| m.Layers++ | |
| } | |
| m.Head0W, _ = get("head.0.w") | |
| m.Head0B, _ = get("head.0.b") | |
| m.Head1W, shp = get("head.1.w") | |
| if shp != nil { | |
| m.C = shp[0] | |
| } | |
| m.Head1B, _ = get("head.1.b") | |
| if _, ok := f.arrays["ctx.w"]; ok { | |
| m.CtxW, _ = get("ctx.w") | |
| m.CtxB, _ = get("ctx.b") | |
| } | |
| if err != nil { | |
| return nil, err | |
| } | |
| if v, ok := f.Info["temperature"].(float64); ok { | |
| m.Temp = v | |
| } | |
| m.Gamma, m.Beta = make([]float32, m.D), make([]float32, m.D) | |
| if _, ok := f.arrays["ctx_pool_default"]; ok { | |
| pool, _ := get("ctx_pool_default") | |
| m.SetContext(pool) | |
| } | |
| return m, nil | |
| } | |
| func gelu(x float32) float32 { | |
| y := float64(x) | |
| return float32(0.5 * y * (1 + math.Tanh(0.7978845608*(y+0.044715*y*y*y)))) | |
| } | |
| func sigmoid32(x float32) float32 { return float32(1 / (1 + math.Exp(-float64(x)))) } | |
| // SetContext derives (gamma, beta) from a pooled benign hidden vector [D] (the site profile). nil = none. | |
| func (m *SeqNet) SetContext(pool []float32) { | |
| for j := range m.Gamma { | |
| m.Gamma[j], m.Beta[j] = 0, 0 | |
| } | |
| if m.CtxW == nil || pool == nil { | |
| return | |
| } | |
| for i := 0; i < 2*m.D; i++ { | |
| s := m.CtxB[i] | |
| for j := 0; j < m.D; j++ { | |
| s += m.CtxW[i*m.D+j] * pool[j] | |
| } | |
| g := float32(math.Tanh(float64(s))) | |
| if i < m.D { | |
| m.Gamma[i] = g | |
| } else { | |
| m.Beta[i-m.D] = g | |
| } | |
| } | |
| } | |
| // NewState allocates one source's GRU state (Layers*D zeros). | |
| func (m *SeqNet) NewState() []float32 { return make([]float32, m.Layers*m.D) } | |
| // Step consumes one flow of a source: numeric features [NumIn], port id, proto id, the source's state (updated | |
| // in place) -> logits [C] (index 0 = attack). scratch may be nil. | |
| func (m *SeqNet) Step(x []float32, port, proto int, state []float32, out, scratch []float32) []float32 { | |
| D := m.D | |
| need := m.In + 2*D + 3*D + 3*D + 64 | |
| if cap(scratch) < need { | |
| scratch = make([]float32, need) | |
| } | |
| scratch = scratch[:need] | |
| z := scratch[:m.In] | |
| copy(z, x[:m.NumIn]) | |
| copy(z[m.NumIn:], m.EmbPort[port*16:port*16+16]) | |
| copy(z[m.NumIn+16:], m.EmbProto[proto*4:proto*4+4]) | |
| h1 := scratch[m.In : m.In+D] | |
| for j := 0; j < D; j++ { | |
| s := m.Enc0B[j] | |
| row := m.Enc0W[j*m.In : j*m.In+m.In] | |
| for i, zi := range z { | |
| s += row[i] * zi | |
| } | |
| h1[j] = gelu(s) | |
| } | |
| inp := scratch[m.In+D : m.In+2*D] | |
| for j := 0; j < D; j++ { | |
| s := m.Enc1B[j] | |
| row := m.Enc1W[j*D : j*D+D] | |
| for i, hi := range h1 { | |
| s += row[i] * hi | |
| } | |
| inp[j] = s | |
| } | |
| gi := scratch[m.In+2*D : m.In+5*D] | |
| gh := scratch[m.In+5*D : m.In+8*D] | |
| for l := 0; l < m.Layers; l++ { | |
| h := state[l*D : l*D+D] | |
| wih, whh := m.WIH[l], m.WHH[l] | |
| for j := 0; j < 3*D; j++ { | |
| s, t := m.BIH[l][j], m.BHH[l][j] | |
| ri, rh := wih[j*D:j*D+D], whh[j*D:j*D+D] | |
| for i := 0; i < D; i++ { | |
| s += ri[i] * inp[i] | |
| t += rh[i] * h[i] | |
| } | |
| gi[j], gh[j] = s, t | |
| } | |
| for j := 0; j < D; j++ { | |
| r := sigmoid32(gi[j] + gh[j]) | |
| zg := sigmoid32(gi[D+j] + gh[D+j]) | |
| n := float32(math.Tanh(float64(gi[2*D+j] + r*gh[2*D+j]))) | |
| h[j] = (1-zg)*n + zg*h[j] | |
| } | |
| copy(inp, h) | |
| } | |
| hh := scratch[m.In+8*D : m.In+8*D+64] | |
| top := state[(m.Layers-1)*D : m.Layers*D] | |
| for j := 0; j < 64; j++ { | |
| s := m.Head0B[j] | |
| row := m.Head0W[j*D : j*D+D] | |
| for i := 0; i < D; i++ { | |
| s += row[i] * (top[i]*(1+m.Gamma[i]) + m.Beta[i]) | |
| } | |
| hh[j] = gelu(s) | |
| } | |
| if cap(out) < m.C { | |
| out = make([]float32, m.C) | |
| } | |
| out = out[:m.C] | |
| for c := 0; c < m.C; c++ { | |
| s := m.Head1B[c] | |
| row := m.Head1W[c*64 : c*64+64] | |
| for i, hi := range hh { | |
| s += row[i] * hi | |
| } | |
| out[c] = s | |
| } | |
| return out | |
| } | |
| // ProbaAttack is sigmoid(logit0 / temperature). | |
| func (m *SeqNet) ProbaAttack(logits []float32) float64 { | |
| return 1 / (1 + math.Exp(-float64(logits[0])/m.Temp)) | |
| } | |