SPB Git

spb/prisme Public MIT

Navigateur iOS intelligent — chaque page comprise localement avant d'être affichée. SwiftUI · WebKit · Foundation Models, 100% on-device.

Swift 96.7% JavaScript 3.3%
1.8 KB · 53 lines swift
Raw Blame History
1//2//  SentenceEmbedder.swift3//  Prisme4//5//  Author: Simon-Pierre Boucher <contact@spboucher.ai>6//78import Foundation9import NaturalLanguage1011/// On-device sentence embeddings (NaturalLanguage framework — no Foundation12/// Models involved, works on every device, offline). Vectors from different13/// language models live in different spaces: the store tags each vector14/// with its language and only compares like with like.15@MainActor16final class SentenceEmbedder {17    private var cache: [NLLanguage: NLEmbedding] = [:]1819    func languageCode(for text: String) -> String? {20        let recognizer = NLLanguageRecognizer()21        recognizer.processString(String(text.prefix(400)))22        return recognizer.dominantLanguage?.rawValue23    }2425    func embed(_ text: String, languageCode: String?) -> [Float]? {26        guard let languageCode else { return nil }27        let language = NLLanguage(rawValue: languageCode)28        let embedding: NLEmbedding?29        if let cached = cache[language] {30            embedding = cached31        } else {32            embedding = NLEmbedding.sentenceEmbedding(for: language)33            if let embedding { cache[language] = embedding }34        }35        guard let vector = embedding?.vector(for: String(text.prefix(600))) else {36            return nil37        }38        return vector.map(Float.init)39    }4041    static func cosine(_ a: [Float], _ b: [Float]) -> Float {42        guard a.count == b.count, !a.isEmpty else { return 0 }43        var dot: Float = 0, normA: Float = 0, normB: Float = 044        for i in a.indices {45            dot += a[i] * b[i]46            normA += a[i] * a[i]47            normB += b[i] * b[i]48        }49        let denominator = (normA.squareRoot() * normB.squareRoot())50        return denominator > 0 ? dot / denominator : 051    }52}53