Go · MaxSim

MaxSim

import "github.com/ashvardanian/NumKong" 8.0.0-rc.1 · b1f866ab

MaxSim is the late-interaction primitive used by systems such as ColBERT. It computes the sum of per-query-token maximum cosine similarities across document tokens. The result is an angular distance: sum(1 - max_cosine).

The MaxSimPackedMatrix struct wraps packed vectors with their metadata.

package main

import (
	"fmt"

	nk "github.com/ashvardanian/NumKong/golang"
)

func main() {
	queryTokens, docTokens, depth := 4, 8, 16

	queries := make([]float32, queryTokens*depth)
	docs := make([]float32, docTokens*depth)
	for i := range queries { queries[i] = float32(i%5) + 1 }
	for i := range docs { docs[i] = float32(i%3) + 1 }

	// Pack both sides
	qPacked := nk.NewMaxSimPackedMatrixF32(queries, queryTokens, depth)
	dPacked := nk.NewMaxSimPackedMatrixF32(docs, docTokens, depth)

	// Compute MaxSim score
	score := nk.MaxSimF32(qPacked, dPacked)
	fmt.Println("MaxSim score:", score)
}

API

StructMaxSimPackedMatrixMaxSimPackedMatrix holds a set of vectors packed once for MaxSimF32.5
maxsim.go:15 ↗
type MaxSimPackedMatrix struct {
    // contains filtered or unexported fields
}

Construct it with NewMaxSimPackedMatrixF32.

NewMaxSimPackedMatrixF32NewMaxSimPackedMatrixF32 packs vectorsCount float32 vectors of depth dimensions for MaxSimF32.
maxsim.go:42 ↗
func NewMaxSimPackedMatrixF32(
    vectorsData []float32,
    vectorsCount, depth int,
) MaxSimPackedMatrix

The slice vectorsData holds at least vectorsCount * depth values.

BytesBytes returns the packed buffer.
maxsim.go:28 ↗
func (p MaxSimPackedMatrix) Bytes() []byte
DepthDepth returns the number of dimensions per packed vector.
maxsim.go:25 ↗
func (p MaxSimPackedMatrix) Depth() int
ShapeShape reads the vector count and depth back from the header of the packed buffer.
maxsim.go:31 ↗
func (p MaxSimPackedMatrix) Shape() (vectors, depth int)
VectorsVectors returns the number of packed vectors.
maxsim.go:22 ↗
func (p MaxSimPackedMatrix) Vectors() int

Functions

MaxSimF32MaxSimF32 sums, over the query vectors, the angular distance from each to its nearest document vector.
numkong.go:59 ↗
func MaxSimF32(query, document MaxSimPackedMatrix) float64

Both matrices must have the same depth.