This is a viewer only at the moment see the article on how this works.
To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk
This is a preview from the server running through my markdig pipeline
Sunday, 21 December 2025
Αυτό είναι ΕΠΙΧΕΙΡΗΣΗ 3 από την σειρά DocSummarizer:
Αυτό είναι μέρος της "Time-Boxed ToolsM SK2 προσέγγισηΜSK3 μου δίνει ένα σταθερό παράθυρο για να χτίσω κάτι λειτουργικόMSKA4 Ενισχύει τις αποφάσεις και παράγει κώδικα εργασίας αντί θεωρητικά σχέδιαMKA5
Το DocSummarizer ξεκίνησε ως μια επίδειξη του πώς Θα πρέπει Δημιουργήστε σύνολα εγγράφων με LLMs - αναφέρθηκε η προσέγγιση του σωλήνα που περιγράψα στο Μέρος ΜSK1 αναφέρθηκαν Τα περισσότερα tutorials σας δείχνουν πώς να σπάσει το κείμενο σε ένα LLM και την ελπίδα για το καλύτερο. αναφέρθηκα θέλω να δείξω τη σωστή αρχιτεκτονικήM SK3 αναφέρθήκαμε αναφέρθέντα, αναφέρουσα ενσωμάτωσηςMK5 αναφέρουμε ανακάλυψη, αναφέρων επικύρωση αναφοράς
Αλλά όπως πάντα κάνω, Έχω ενδιαφέρον για το χώρο προβλήματοςΜSK1 Τέσσερις ημέρες αργότερα,Έχω ενδιαφέρον'Διακόπτει στην έρευναM SK4Πώς η παραγωγήMK5Συστήματα αναβάθμισης πραγματικά χειρίζονται τη συνοψίαMSKA6Τι κάνει την ανάκτηση εργασία καλάMKA7Γιατί κάνουν μερικές ενσωμάτωση υπερβαίνει άλλουςMCA8
Εφαρμόστηκα εκδόσεις αυτών των προσεγγίσεων. Τι ξεκίνησε με "ΜSK2 το σωστό πρότυποM SK3 έγινε ONNX ενσωμάτωσης που τρέχει τοπικάMK4 υβριδική αναζήτηση συνδυάζοντας BM25 με πυκνό ανάκτημα, Μέγιστη περιθωριακή σχετικότητα για την ποικιλομορφίαMST7 και Reciprocal Rank Fusion για τη σύνδεση σήματοςMSC8
Δίκαιη προειδοποίηση: Αυτό είναι το "Έχω πάει πολύ μακριάΜSK2 βαθιά βυθίζοντας ΜSK3 Εάν θέλετε απλά να χρησιμοποιήσετε το εργαλείο ΜСК4 διαβάστε Μέρος ΜΣΚ5 Αν θέλετε να καταλάβετε Γιατί λειτουργεί και Πώς Τα κομμάτια ταιριάζουν μαζί, Συνεχίστε την ανάγνωση.
Αυτό το άρθρο καλύπτει:
Πριν βυθίσουμε σε συγκεκριμένα, εδώΜSK1 πώς τα κομμάτια ταιριάζουν μαζί:
flowchart TB
subgraph Input["Document Input"]
DOC[/"Document<br/>(PDF, MD, URL)"/]
end
subgraph Parse["Parsing Layer"]
DOCLING["Docling<br/>(PDF/DOCX)"]
MARKDIG["Markdig<br/>(Markdown)"]
end
subgraph Extract["Extraction Layer"]
CHUNK["Document Chunker"]
SEGMENT["Segment Extractor"]
end
subgraph Embed["Embedding Layer"]
ONNX["ONNX Runtime<br/>(Sentence Transformers)"]
OLLAMA_EMB["Ollama<br/>(Optional)"]
end
subgraph Store["Vector Storage"]
QDRANT["Qdrant<br/>(Vector DB)"]
MEMORY["In-Memory<br/>(Small Docs)"]
end
subgraph Retrieve["Retrieval Layer"]
DENSE["Dense Search<br/>(Semantic)"]
BM25["BM25<br/>(Lexical)"]
RRF["RRF Fusion"]
end
subgraph Synthesize["Synthesis Layer"]
OLLAMA["Ollama LLM<br/>(Local)"]
TEMPLATES["Summary Templates"]
end
subgraph Output["Output"]
SUMMARY[/"Summary with<br/>Citations [chunk-N]"/]
end
DOC --> DOCLING & MARKDIG
DOCLING & MARKDIG --> CHUNK & SEGMENT
CHUNK --> ONNX & OLLAMA_EMB
SEGMENT --> ONNX
ONNX & OLLAMA_EMB --> QDRANT & MEMORY
QDRANT & MEMORY --> DENSE
CHUNK --> BM25
DENSE & BM25 --> RRF
RRF --> OLLAMA
OLLAMA --> TEMPLATES
TEMPLATES --> SUMMARY
Όταν συνοψίζετε ένα εγχειρίδιο αναζήτησης 500-ΜSK1 θα πρέπει να βρείτε σχετικές ενότητες. Παραδοσιακή αναζήτηση λέξεων-κλειδιών αποτυγχάνει
χρειάζεσαι Σημαντική αναζήτηση - ταιριάζει με την έννοιαΜSK1 όχι μόνο λέξεις.
Οι ενσωμάτωσεις επιλύουν αυτό μετατρέποντας το κείμενο σε πυκνούς vectors ( αναφορές αριθμών ΜSK1 αναφέρουν ότι η σύλληψη σημαίνει σημαντική ΜSK2 αναφέρει Παρόμοιες έννοιες = αναφέρει παρόμοιους vectors Μ SK4 αναφέρθηκε ανεξάρτητα από την ακριβή γραφή
Εδώ ' ικανοποιεί τη διαίσθηση ΜSK1 ικανό να φανταστεί ένα ΜSK2 ικανή διάσταση χώρο όπου κάθε κομμάτι κειμένου έχει μια θέση . ικανότητα κειμένων με παρόμοιες έννοιες συγκέντρωση μαζί
graph LR
subgraph "Embedding Space (simplified to 2D)"
A["🚗 car"]
B["🚙 automobile"]
C["🏎️ vehicle"]
D["🍎 apple"]
E["🍊 orange"]
F["🍌 fruit"]
end
A -.->|"close"| B
B -.->|"close"| C
A -.->|"close"| C
D -.->|"close"| E
E -.->|"close"| F
D -.->|"close"| F
A -.-|"far"| D
Πρόβλημα: Χρειαζόμουν ενσωμάτωση που λειτουργεί για την σημαντική ομοιότηταΜSK1 Το Raw BERT έχει σχεδιαστεί για τα καθήκοντα ταξινόμησηςΗ , δεν αναζητά ομοιότητεςΗ ΜSK3
Λύση: Χρήση Γνώμη μετασχηματιστών - αναφέρει μοντέλα ειδικά εκπαιδευμένα σε καθήκοντα ομοιότητας χρησιμοποιώντας αντίθετη μάθηση ΜSK1 αναφέρει ότι το ' αναφέρει με βάση την Αρχιτεκτονική BERT Αξίζει να σημειωθεί ότι το .
Μοντέλα όπως all-MiniLM-L6-v2 και bge-small-en-v1.5 Εκπαιδεύτηκαν σε δισεκατομμύρια ζευγάρια κειμένου όπως:
Η κατάρτιση τους διδάσκει: παρόμοιες έννοιες ΜSK1 στενούς vectors Η ΜSK2 συνειδητή ομοιότηταΗ ).
Σχετικά: Εάν θέλετε να καταλάβετε πώς λειτουργούν τα μοντέλα μετασχηματιστών σε βαθύτερο επίπεδο ΜSK1 συμπεριλαμβανομένων των μηχανισμών προσοχής ΜSK2 κωδικοποίηση - αρχιτεκτονική αποκρυπτογράφησης ΜСК4 και γιατί λειτουργούν οι ενσωμάτωσες ΜΚ5 δείτε το άρθρο μου στο Πώς λειτουργεί η Neural Machine Translation. καλύπτει τις ίδιες έννοιες μετασχηματιστών από μια προοπτική μετάφρασηςΜSK1
εφαρμογή: Λαμβάνουμε το μοντέλοΗ ' αναφέρει την επιφάνεια εξόδου και εφαρμόζει Μιλάμε για τη συγχώνευση - μέση ενσωμάτωση όλων των tokens για να πάρει ένα μόνο vector για ολόκληρο το κείμενοΜSK1
flowchart LR
subgraph Input
TEXT["The quick brown fox"]
end
subgraph Tokenization
CLS["[CLS]"]
T1["the"]
T2["quick"]
T3["brown"]
T4["fox"]
SEP["[SEP]"]
end
subgraph "BERT Encoder"
direction TB
L1["Layer 1: Self-Attention"]
L2["Layer 2: Self-Attention"]
L3["..."]
L6["Layer 6: Self-Attention"]
end
subgraph Output
E1["E[CLS]"]
E2["E[the]"]
E3["E[quick]"]
E4["E[brown]"]
E5["E[fox]"]
E6["E[SEP]"]
end
subgraph Pooling
MEAN["Mean Pool<br/>(with attention mask)"]
VEC["384-dim Vector"]
end
TEXT --> CLS & T1 & T2 & T3 & T4 & SEP
CLS & T1 & T2 & T3 & T4 & SEP --> L1
L1 --> L2 --> L3 --> L6
L6 --> E1 & E2 & E3 & E4 & E5 & E6
E1 & E2 & E3 & E4 & E5 & E6 --> MEAN
MEAN --> VEC
Ήθελα ενσωμάτωση σε " προσαρμογή εργασίας ΜSK1 όταν κάποιος τρέχει το εργαλείο ΜSK2 Η τυπική προσέγγιση :
Αυτό συμβαίνει. Οι χρήστες θέλουν docsummarizer -f doc.pdf, όχι ΜSK1οδηγός εγκατάστασης.
ONNX (Open Neural Network ExchangeΗ ) είναι μια ανοικτή μορφή για τα μοντέλα MLΤο χαρακτηριστικό δολοφονίαςη : Δραστηριότητες χωρίς Python.
Τι μπορώ να κάνω με το ONNX Runtime:
Εμπόριο-ΜSK1 Λίγο πιο αργά από GPU PyTorch, αλλά πολύ γρηγορότερα από το να ζητάτε από τους χρήστες να εγκαταστήσουν PythonM SK3
Το DocSummarizer περιλαμβάνει διάφορα ενσωματωμένα μοντέλα, ο καθένας με διαφορετικά εμπορικάΜSK1:
| Μοντέλο ΜSK1 Μετρήματα ΜSK2 Μαξ Τόκενς | Μέγεθος (Quantized) MK6 Χρησιμοποιήστε την περίπτωση MC7 Απαιτείτε οδηγίες SMK8 | ||
|---|---|---|---|
AllMiniLmL6V2 ΜΣΚ0 ΜΣΚ1 MΣΚ2 MSSK3 |
MSM5MB | Προεπιλεγμένη MSM7 γρήγορη , καλή ποιότητα | Όχι |
BgeSmallEnV15 ΜΣΚ0 ΜΣΚ1 MΣΚ2 ΜΑΣΚ3 ΜΕΣΚ4 ΜΙΣΚ5MB |
Καλύτερα για τεχνικές δοκίμια | Ναι | |
GteSmall ΜΣΚ0 ΜΣΚ1 MΣΚ2 ΜΑΣΚ3 ΜΕΣΚ4 ΜΙΣΚ5MB |
Γενικός σκοπός | Όχι | |
MultiQaMiniLm ΜΣΚ0 ΜΣΚ1 MΣΚ2 ΜΑΣΚ3 ΜΑΣΚ4 ΜΗΣΚ5ΜΒ |
Βελτιστοποιημένο για QΜσΚ7Α Γ. |
Σημείωση: Όλες οι εισαγωγές καταχώρισης υποδεικνύουν το WordPieceΜSK1συμβατικές εξαγωγές ONNX Η χρήση του ( vocab.txt). BPE / Τα μοντέλα του Unigram δεν υποστηρίζονται ακόμη ΜSK2
BGE μορφή διδασκαλίας: Μερικά μοντέλα Η ( όπως η BGE και η ) απαιτούν προσαρμογές για βέλτιστες επιδόσεις Η . Η ακριβής μορφή εξαρτάται από το μοντέλοΗ
// Query embedding (what the user asks)
var queryText = "Represent this sentence for searching relevant passages: " + userQuery;
var queryEmbedding = await EmbedAsync(queryText);
// Passage embedding (document chunks)
// Some BGE variants prefix passages, others don't - check model documentation
var passageEmbedding = await EmbedAsync(chunkText);
Το μητρώο παρακολουθεί ποια μοντέλα χρειάζονται οδηγίες μέσω RequiresInstruction και QueryInstruction πεδία. Πάντα αναφορά ποιότητας ανάκτησης όταν εργάζονται με την εκπαίδευσηΜSK1μεταφερόμενα μοντέλα.
Εδώ' αναφέρει πώς λειτουργεί το μητρώο μοντέλων:
public static class OnnxModelRegistry
{
public static EmbeddingModelInfo GetEmbeddingModel(OnnxEmbeddingModel model, bool quantized = true)
{
return model switch
{
OnnxEmbeddingModel.AllMiniLmL6V2 => new EmbeddingModelInfo
{
Name = "all-MiniLM-L6-v2",
HuggingFaceRepo = "Xenova/all-MiniLM-L6-v2",
ModelFile = quantized ? "onnx/model_quantized.onnx" : "onnx/model.onnx",
VocabFile = "vocab.txt",
EmbeddingDimension = 384,
MaxSequenceLength = 256,
SizeBytes = quantized ? 23_000_000 : 90_000_000,
RequiresInstruction = false
},
// ... other models
};
}
}
Διαφορετικά μοντέλα χρησιμοποιούν διαφορετικούς tokenizers. all-MiniLM-L6-v2 Το μοντέλο χρησιμοποιεί το tokenization του WordPiece ( σε σχέση με BERT ΜSK1 που διαιρεί άγνωστες λέξεις σε τακούνια υπογραμμάτων ΜSK2 Άλλα μοντέλα μπορούν να χρησιμοποιήσουν BPE (Byte
Σημαντικό: Οι tokenizers μοντέλου πρέπει να ταιριάζουν με τον εκπαιδευτικό tokenizer για το . Τα αποτυπώματα του μητρώου μας τα οποία απαιτούνται από κάθε μοντέλο για το tokeniser για το MK2 Προς το παρόν εφαρμόζεται: WordPiece ΚΕΦΑΛΑΙΟ 0 vocab.txt). BPE /Unigram υποστήριξη μέσω tokenizer.json είναι προγραμματισμένο αλλά δεν έχει ακόμη εφαρμοστεί - ενδεχομένως να παραμείνει στα μοντέλα του WordPiece στο μητρώο για τώραΜSK1 ενδέχεται
public class BertTokenizer
{
private readonly Dictionary<string, int> _vocab;
private const int ClsTokenId = 101; // [CLS] - start of sequence
private const int SepTokenId = 102; // [SEP] - end of sequence
private const int PadTokenId = 0; // [PAD] - padding
private const int UnkTokenId = 100; // [UNK] - unknown token
public BertTokenizer(string vocabPath)
{
// Load vocabulary: word -> token ID
_vocab = File.ReadAllLines(vocabPath)
.Select((word, index) => (word, index))
.ToDictionary(x => x.word, x => x.index);
}
public (long[] InputIds, long[] AttentionMask, long[] TokenTypeIds)
Encode(string text, int maxLength)
{
// Split text into words, then apply WordPiece to each word
var words = text.ToLowerInvariant()
.Split(new[] { ' ', '\t', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
var tokens = words.SelectMany(WordPieceTokenize).ToList();
// Truncate to fit [CLS] and [SEP] tokens
if (tokens.Count > maxLength - 2)
tokens = tokens.Take(maxLength - 2).ToList();
// Build input: [CLS] + tokens + [SEP] + [PAD]...
var inputIds = new List<long> { ClsTokenId };
inputIds.AddRange(tokens.Select(t => (long)GetTokenId(t)));
inputIds.Add(SepTokenId);
// Pad to maxLength
var padCount = maxLength - inputIds.Count;
inputIds.AddRange(Enumerable.Repeat((long)PadTokenId, padCount));
// Attention mask: 1 for real tokens, 0 for padding
var attentionMask = inputIds.Select(id => id != PadTokenId ? 1L : 0L).ToArray();
// Token type IDs: all zeros for single sentence
var tokenTypeIds = new long[maxLength];
return (inputIds.ToArray(), attentionMask, tokenTypeIds);
}
private IEnumerable<string> WordPieceTokenize(string word)
{
// If the whole word is in vocabulary, return it
if (_vocab.ContainsKey(word))
{
yield return word;
yield break;
}
// Otherwise, split into subwords with "##" prefix
int start = 0;
while (start < word.Length)
{
int end = word.Length;
string? curSubstr = null;
while (start < end)
{
var substr = word[start..end];
if (start > 0) substr = "##" + substr; // Continuation marker
if (_vocab.ContainsKey(substr))
{
curSubstr = substr;
break;
}
end--;
}
if (curSubstr == null)
{
yield return "[UNK]";
yield break;
}
yield return curSubstr;
start = end;
}
}
}
Ετικέτες :
| Εισαγωγή ΜSK1 Τοξίνες ΜSK2 | |
|---|---|
"embedding" |
["em", "##bed", "##ding"] |
"DocSummarizer" |
["doc", "##su", "##mm", "##ari", "##zer"] |
"the quick brown" |
["the", "quick", "brown"] |
Μετά το BERT επεξεργάζεται τα tokens, λαμβάνουμε μια κρυμμένη κατάσταση για κάθε token. Μέση συγκέντρωση μέσους όρους αυτάΜSK2 αλλά μόνο πάνω από πραγματικά tokens M SK3 δεν paddingMK4
private static float[] MeanPool(Tensor<float> hiddenStates, long[] attentionMask, int hiddenSize)
{
// Assumes last_hidden_state shape: [batch=1, seq_len, hidden_size]
// Note: Many sentence-transformer models export a pooled output directly,
// but we use mean pooling for consistency across all ONNX exports.
var result = new float[hiddenSize];
var dims = hiddenStates.Dimensions.ToArray();
var seqLen = (int)dims[1];
// Count real tokens (not padding)
float maskSum = attentionMask.Count(x => x == 1);
if (maskSum == 0) maskSum = 1; // Avoid division by zero
// Average each dimension, weighted by attention mask
for (int h = 0; h < hiddenSize; h++)
{
float sum = 0;
for (int s = 0; s < seqLen; s++)
{
if (attentionMask[s] == 1)
sum += hiddenStates[0, s, h];
}
result[h] = sum / maskSum;
}
// L2 normalize for cosine similarity
float norm = MathF.Sqrt(result.Sum(x => x * x));
if (norm > 0)
{
for (int i = 0; i < result.Length; i++)
result[i] /= norm;
}
return result;
}
Εδώ' διατηρεί την πλήρη ροή από το κείμενο στην ενσωμάτωση:
public class OnnxEmbeddingService : IEmbeddingService, IDisposable
{
private InferenceSession? _session;
private BertTokenizer? _tokenizer;
public async Task<float[]> EmbedAsync(string text, CancellationToken ct = default)
{
await InitializeAsync(ct); // Downloads model if needed
// Prepend instruction for models that need it (like BGE)
if (_modelInfo.RequiresInstruction)
text = _modelInfo.QueryInstruction + text;
// Tokenize
var (inputIds, attentionMask, tokenTypeIds) =
_tokenizer.Encode(text, _maxSequenceLength);
// Create ONNX tensors
var inputIdsTensor = new DenseTensor<long>(inputIds, new[] { 1, inputIds.Length });
var attentionMaskTensor = new DenseTensor<long>(attentionMask, new[] { 1, attentionMask.Length });
var tokenTypeIdsTensor = new DenseTensor<long>(tokenTypeIds, new[] { 1, tokenTypeIds.Length });
var inputs = new List<NamedOnnxValue>
{
NamedOnnxValue.CreateFromTensor("input_ids", inputIdsTensor),
NamedOnnxValue.CreateFromTensor("attention_mask", attentionMaskTensor),
NamedOnnxValue.CreateFromTensor("token_type_ids", tokenTypeIdsTensor)
};
// Run inference
using var results = _session.Run(inputs);
// Get hidden states output
var output = results.First(r => r.Name == "last_hidden_state");
var outputTensor = output.AsTensor<float>();
// Mean pooling with attention mask
return MeanPool(outputTensor, attentionMask, _modelInfo.EmbeddingDimension);
}
}
Η αφελής προσέγγιση αποτύχει:
var text = File.ReadAllText("500-page-manual.txt"); // 2MB of text
var summary = await llm.GenerateAsync($"Summarize: {text}"); // ❌ Doesn't fit in context
Ακόμη και με τα 128K πλαίσια παράθυραΜSK1 μπορείτε να κάνετε το ' απλά σπάσει τεράστια έγγραφα σε:
Αντί να στείλετε όλα τα, επιχειρήσεις στέλνετε μόνο αυτό πουΜSK1 αναφέρει σχετικό: επιχειρήσεις
Γιατί αυτό λειτουργεί: Το LLM βλέπει 10KB του πολύ σχετικού περιεχομένου αντί για ΜSK1MB του συνήθως irrelevant κειμένου.
flowchart LR
subgraph "Without RAG"
DOC1[/"500-page PDF"/]
LLM1["LLM<br/>(32K context)"]
OUT1["❌ Truncated or<br/>Hallucinated"]
end
subgraph "With RAG"
DOC2[/"500-page PDF"/]
CHUNKS["100 Chunks"]
VDB["Vector DB"]
QUERY["Query"]
TOP["Top 10 Chunks"]
LLM2["LLM"]
OUT2["✅ Grounded<br/>Summary"]
end
DOC1 --> LLM1 --> OUT1
DOC2 --> CHUNKS --> VDB
QUERY --> VDB --> TOP --> LLM2 --> OUT2
Το DocSummarizer υποστηρίζει πολλαπλές στρατηγικές που βασίζονται στη δομή εγγράφων:
public class DocumentChunker
{
public List<DocumentChunk> ChunkByHeadings(string markdown, int maxHeadingLevel = 2)
{
var chunks = new List<DocumentChunk>();
var lines = markdown.Split('\n');
var currentChunk = new StringBuilder();
var currentHeading = "";
var headingLevel = 0;
var order = 0;
foreach (var line in lines)
{
// Detect heading (# to ######)
var headingMatch = Regex.Match(line, @"^(#{1,6})\s+(.+)$");
if (headingMatch.Success &&
headingMatch.Groups[1].Length <= maxHeadingLevel)
{
// Flush current chunk
if (currentChunk.Length > 0)
{
chunks.Add(new DocumentChunk(
Order: order++,
Heading: currentHeading,
HeadingLevel: headingLevel,
Content: currentChunk.ToString().Trim(),
Hash: ComputeHash(currentChunk.ToString())
));
}
// Start new chunk
currentHeading = headingMatch.Groups[2].Value;
headingLevel = headingMatch.Groups[1].Length;
currentChunk.Clear();
}
else
{
currentChunk.AppendLine(line);
}
}
// Don't forget the last chunk
if (currentChunk.Length > 0)
{
chunks.Add(new DocumentChunk(
Order: order,
Heading: currentHeading,
HeadingLevel: headingLevel,
Content: currentChunk.ToString().Trim(),
Hash: ComputeHash(currentChunk.ToString())
));
}
return chunks;
}
}
Για μεγαλύτερα έγγραφα , DocSummarizer εξάγει μεμονωμένα τμήματα ( αναφορές ΜSK2 αναφορές στοιχεία λίστας ΜSK3 αναφορές μπλοκ κώδικας
public class SegmentExtractor
{
public async Task<ExtractionResult> ExtractAsync(string docId, string markdown)
{
// 1. Parse into typed segments
var segments = ParseToSegments(docId, markdown);
// 2. Generate embeddings
await GenerateEmbeddingsAsync(segments);
// 3. Calculate document centroid (average embedding)
var centroid = CalculateCentroid(segments);
// 4. Score by salience using MMR (Maximal Marginal Relevance)
ComputeSalienceScores(segments, centroid);
return new ExtractionResult
{
AllSegments = segments,
TopBySalience = segments.OrderByDescending(s => s.SalienceScore).Take(50).ToList(),
Centroid = centroid
};
}
}
Χωρίς MMR, ανάκληση για ΜSK1Πώς λειτουργεί το cachingΗ ?" επιστρέφειΗ ΜSK3
Το κορυφαίο 3 αναφέρει τα αποτελέσματα όλα λένε το ίδιο πράγμα ΜSK1 αναφέρω ' αναμένεται να σπαταλήσει το παράθυρο πλαίσιο για την επανάληψη
Εξισορρόπηση MMR Σημαντικότητα (ομοιότητες για να ζητήσετεΜSK1 με ποικιλομορφία (διαφορετικότητα σε ήδη ληφθεί-Επιλεγμένα αντικείμεναΜSK2
Φόρμουλα: ΜΣΚ0MMR = ΜΣΚ2lambda \cdot \text ΜSK5simΜSK6 ΜСК7 ερώτηση ΜΚ8 Μσκ9 Μск10 Μスク11 Μsk12lombda Μ스크13 Μسک14cdo_{σεΜSK1σε \σε επιλεγμένο}σε ΜSK4textM SK5simMK6σε
ΤΙ ΕΙΝΑΙ ΠΡΟΣΩΠΙΚΟ ΣΧΕΔΙ Ποινικοποιεί τους υποψηφίους παρόμοιους με εκείνους που έχουν ήδη ανακοινωθεί- μη επιλεγμένα τμήματα. Αυτό εμποδίζει το σύνολο να είναι ΜSK2 ανακοινώθηκε εκδόσεις της ίδιας παραγράφου.
flowchart TB
subgraph "MMR Selection"
S1["Segment 1<br/>Score: 0.95"]
S2["Segment 2<br/>Score: 0.90"]
S3["Segment 3<br/>Score: 0.88"]
S4["Segment 4<br/>Score: 0.85"]
end
subgraph "Selected"
SEL1["✓ Seg 1<br/>(highest)"]
SEL2["✓ Seg 3<br/>(most diverse)"]
SEL3["✓ Seg 4"]
end
S1 -->|"Select"| SEL1
S2 -->|"Skip - too similar to Seg 1"| X["❌"]
S3 -->|"Select"| SEL2
S4 -->|"Select"| SEL3
Η φόρμουλα:
$$MMR ΜSK1 ΜSK2lambda \cdot sim(M SK5 centroidMK6_{σεΜSK1σε \σε Επιλεγμένο}σε SIMσε(σε ΜSK5σε
private List<Segment> SelectSentencesMMR(
List<Segment> segments,
float[] centroid,
int targetCount)
{
var selected = new List<Segment>();
var candidates = new HashSet<Segment>(segments.Where(s => s.Embedding != null));
// Pre-calculate centroid similarities
foreach (var segment in candidates)
{
segment.Score = CosineSimilarity(segment.Embedding!, centroid)
* segment.PositionWeight;
}
while (selected.Count < targetCount && candidates.Count > 0)
{
Segment? best = null;
double bestScore = double.MinValue;
foreach (var candidate in candidates)
{
// Relevance: similarity to centroid
var relevance = candidate.Score;
// Diversity: max similarity to already selected
double maxSimToSelected = 0;
foreach (var sel in selected)
{
var sim = CosineSimilarity(candidate.Embedding!, sel.Embedding!);
maxSimToSelected = Math.Max(maxSimToSelected, sim);
}
// MMR score: balance relevance and diversity
var mmrScore = _config.Lambda * relevance
- (1 - _config.Lambda) * maxSimToSelected;
if (mmrScore > bestScore)
{
bestScore = mmrScore;
best = candidate;
}
}
if (best != null)
{
selected.Add(best);
candidates.Remove(best);
}
}
return selected;
}
Πήγα σε αυτό όταν δοκιμάζω:
Ζητήστε: ΜSK1Τι γνωρίζει το ' για το τελικό σημείο API για την εξακρίβωση?"
Σεμάντικη αναζήτηση επιστρέφει:
Τι λείπει: Το πραγματικό τελικό σημείο API κρυμμένο σε παραδείγματα κωδικούΜSK1 POST /api/v1/auth/login
Γιατί: Τα ενσωματωμένα μοντέλα εκπαιδεύονται σε φυσική γλώσσαM SK1 δεν κωδικοποιεί/URLsMK3 ακριβείς όρουςMST4 Το τελικό σημείο POST /api/v1/auth/login ' " Αυτοποίηση τελικού σημείου ΜSK2 ΜSK3 ' Έχει γραπτή τεχνική αναφορά
Συνδυάστε δύο μεθόδους ανάκτησης με συμπληρωματικές δυνάμεις:
| Τύπος αναζήτησης ΜSK1 Δυνάμεις ΜSK2 αδυναμίες | |
|---|---|
| ΕΡΓΑΣΙΑ ΜΑΘΗΜΑ 1 ΕΠΙΤΡΟΦΟ | Σεμάντικη κατανόησηΜSK1 συνώνυμες ΜSK2 Μπορεί να χάσει τα ακριβή παιχνίδια ΜСК3 σπάνιες όροι ΜΚ4 |
| Εξοικονόμηση (BMΜSK1 | Ακριβής αντιστοιχία λέξεων-κλειδιώνΜSK1 σπάνιοι όροι ΜΣΚ2 Χωρίς σεμνητική κατανόηση ΜΣΚ3 |
Η υβριδική αναζήτηση συνδυάζει και τα δύο με τη χρήση της Reciprocal Rank Fusion (RRF):
flowchart TB
QUERY["Query: 'authentication security'"]
subgraph Dense["Dense Search (Semantic)"]
D1["1. OAuth 2.0 implementation"]
D2["2. User login flow"]
D3["3. Password hashing"]
end
subgraph Sparse["BM25 Search (Lexical)"]
S1["1. Authentication middleware"]
S2["2. Security headers"]
S3["3. OAuth 2.0 implementation"]
end
subgraph RRF["RRF Fusion (Illustrative)"]
R1["OAuth 2.0 implementation<br/>RRF = 1/(60+1) + 1/(60+3) ≈ 0.032"]
R2["Authentication middleware<br/>RRF = (not in dense) + 1/(60+1) ≈ 0.016"]
R3["User login flow<br/>RRF = 1/(60+2) + (not in BM25) ≈ 0.016"]
end
QUERY --> Dense & Sparse
Dense --> RRF
Sparse --> RRF
Σημείωση: Τα αποτελέσματα RRF που εμφανίζονται είναι εικονογραφητικάΜSK1 Η σταθερή k=60 είναι τυποποιημένηΗ πραγματική κατάταξη του ; εξαρτάται από το πλήρες υποψήφιο σύνολο
public static class HybridRRF
{
/// <summary>
/// Reciprocal Rank Fusion: combine multiple rankings into one.
///
/// Formula: RRF(d) = Σ 1/(k + rank_i(d))
///
/// Where k = 60 (standard constant to prevent division by small numbers)
/// </summary>
public static List<Segment> Fuse(
List<Segment> segments,
string query,
BM25Scorer bm25,
int k = 60,
int topK = 20)
{
// Rank by dense similarity
var byDense = segments
.Where(s => s.Embedding != null)
.OrderByDescending(s => s.QuerySimilarity)
.ToList();
// Rank by BM25 (scorer is built over the same ordered segment list)
var bm25Scores = segments
.Select((s, i) => (segment: s, score: bm25.Score(i, query)))
.OrderByDescending(x => x.score)
.Select(x => x.segment)
.ToList();
// Rank by salience (pre-computed importance)
var bySalience = segments
.OrderByDescending(s => s.SalienceScore)
.ToList();
// Compute RRF scores
var rrfScores = new Dictionary<Segment, double>();
void AddRRFScore(List<Segment> ranking)
{
for (int i = 0; i < ranking.Count; i++)
{
var segment = ranking[i];
var rrfContribution = 1.0 / (k + i + 1); // 1-based rank
if (!rrfScores.TryAdd(segment, rrfContribution))
rrfScores[segment] += rrfContribution;
}
}
AddRRFScore(byDense);
AddRRFScore(bm25Scores);
AddRRFScore(bySalience);
// Return top-K by fused score
return rrfScores
.OrderByDescending(kv => kv.Value)
.Take(topK)
.Select(kv => kv.Key)
.ToList();
}
}
BM25 ( Καλύτερη Συμφωνία ΜSK2 είναι ο κλασικός αλγόριθμος ανακάλυψης πληροφοριών ΜΚ3 Συνδυάζει συχνότητα όρου ΜΣΚ4 αντιστροφική συχνότητα εγγράφου ΜСК5 και τυποποίηση μήκους έγγραφα ΜΚΑ6
public class BM25Scorer
{
private const double K1 = 1.5; // Term frequency saturation
private const double B = 0.75; // Length normalization factor
public double Score(int docIndex, string query)
{
var queryTerms = Tokenize(query);
var docTermFreq = _docTermFreqs[docIndex];
var docLength = _docLengths[docIndex];
double score = 0;
foreach (var term in queryTerms.Distinct())
{
if (!docTermFreq.TryGetValue(term, out var tf)) continue;
if (!_docFreqs.TryGetValue(term, out var df)) continue;
// IDF with smoothing
var idf = Math.Log((_corpusSize - df + 0.5) / (df + 0.5) + 1);
// BM25 TF component with length normalization
var tfNorm = (tf * (K1 + 1)) /
(tf + K1 * (1 - B + B * docLength / _avgDocLength));
score += idf * tfNorm;
}
return score;
}
}
Συνοψίζοντας ένα μυθιστόρημα, έλαβα αποτελέσματα όπως:
"Ο πρωταγωνιστής φορούσε ένα μπλε καπέλοΜSK1 Ο Watson σημείωσε ότι ο καιρός ήταν ελαφρύ ΜSK2 Η μελέτη είχε έπιπλα
Αυτά είναι ακριβή εκχυλίσματα ειδικά, επιχειρήσεις, αλλά ειδικότερα' αναφέρει Χρώμα ( αναθεώρηση ΜSK1 αναθεωρήσεις λεπτομέρειες ΜSK2 δεν Κύρια σημεία κλάσης.
Η πρόκληση: Πώς να πείτε τη διαφορά μεταξύΜSK1
TF-IDF (Τερματική Συχνότητα ΜSK2 Αντίστροφη Συχνότητα ΕγγράφουΣυγκριτικές εκτιμήσεις Πόσο κεντρικός είναι ο όρος στο έγγραφο, σίγουρα δεν έχει την αληθινή του αξία.
ΛΟΓΙΚΕΣ ΕΠΙΧΕΙΡΕΥΣΕΙΣ
Αυτό δεν είναι αλήθεια (a επαναλαμβανόμενες αξιώσεις μπορεί να είναι ψευδείςΜSK1 ένα σπάνιο γεγονός μπορεί να ήταν αληθινό).ΑυτόM SK3 Κεντρικότητα του εγγράφου.
flowchart LR
subgraph "TF-IDF Classification"
CLAIM["Claim text"]
TERMS["Extract terms"]
TFIDF["Compute TF-IDF"]
CLASS["Classify"]
end
subgraph "Term Types"
COMMON["High DF (>50%)<br/>→ Core content"]
MODERATE["Medium DF (20-50%)<br/>→ Supporting detail"]
RARE["Low DF (<20%)<br/>→ Incidental colour"]
end
CLAIM --> TERMS --> TFIDF --> CLASS
CLASS --> COMMON & MODERATE & RARE
public class TextAnalysisService
{
private readonly Dictionary<string, int> _documentFrequency = new();
private int _totalDocuments;
public void BuildTfIdfIndex(IEnumerable<string> documents)
{
_documentFrequency.Clear();
_totalDocuments = 0;
foreach (var doc in documents)
{
_totalDocuments++;
var terms = Tokenize(doc).Distinct();
foreach (var term in terms)
{
_documentFrequency.TryGetValue(term, out var count);
_documentFrequency[term] = count + 1;
}
}
}
/// <summary>
/// Classify term centrality (not epistemic truth):
/// - High DF (>50%): appears across most chunks = core content
/// - Medium DF (20-50%): supporting detail
/// - Low DF (<20%): rare = likely incidental ("colour")
///
/// Note: This estimates centrality, not factuality. A repeated
/// claim can be false; a rare fact can be true.
/// </summary>
public ClaimType ClassifyTermImportance(string term)
{
var df = _documentFrequency.GetValueOrDefault(term.ToLowerInvariant(), 0);
if (_totalDocuments == 0 || df == 0)
return ClaimType.Colour;
var documentRatio = (double)df / _totalDocuments;
// High centrality = appears widely
if (documentRatio > 0.5)
return ClaimType.Core;
// Medium centrality = supporting themes
if (documentRatio > 0.2)
return ClaimType.Supporting;
// Low centrality = incidental detail
return ClaimType.Colour;
}
}
DocSummarizer' παραγωγικό σωλήνα ΜSK1BertRagSummarizer) συνδυάζει όλες αυτές τις έννοιεςΜSK1
public class BertRagSummarizer
{
/// <summary>
/// Full pipeline: Extract → Retrieve → Synthesize
///
/// Key properties:
/// - LLM only at synthesis (no LLM-in-the-loop evaluation)
/// - Deterministic extraction (reproducible, debuggable)
/// - Validated citations (every claim traceable to source segment)
/// - Scales to any document size
/// - Cost-optimal (cheap CPU work first, expensive LLM last)
/// </summary>
public async Task<DocumentSummary> SummarizeAsync(
string docId,
string markdown,
string? focusQuery = null)
{
// === Phase 1: Extract ===
// Parse document → segments with embeddings + salience scores
var extraction = await _extractor.ExtractAsync(docId, markdown);
// === Phase 2: Retrieve ===
// Hybrid search: Dense + BM25 + Salience via RRF
var retrieved = await RetrieveAsync(extraction, focusQuery);
// === Phase 3: Synthesize ===
// LLM generates fluent summary from retrieved segments
var summary = await SynthesizeAsync(docId, retrieved, extraction, focusQuery);
return summary;
}
}
Όταν χτίζετε και χρησιμοποιείτε το DocSummarizer,I'έτυχε αυτά τα προβλήματα ΜSK2και θα σας αρέσει επίσης):
Τόκενιζερ λανθασμένα → ανοησίες ενσωμάτωσης: Κατεβάζοντας ένα λεξιλόγιο WordPiece για ένα BPEΜSK1 διατηρημένο μοντέλο παράγει έγκυρο- προβλέψιμο, αλλά σεμάντικα άχρηστο vectorsM SK3 Πάντα επαληθεύστε το tokenizer ταιριάζει με το μοντέλαMSKA4 αναγνωρίζει εκπαιδευτικό καθεστώςMKA5
Η κυριαρχία των -τοπικών bias σε ένα-κεντροειδείς βαθμολογίες: Χρησιμοποιώντας ένα έγγραφο κεντροειδές συστηματικά κατεβάσει- αναγνωρίζει θέματα μειοψηφίας ΜSK2 αναγνωρίζοντας διαφορές ΜSK3 αναγνωρίστε εξαιρέσεις , αναγνωρίζεται περιπτώσεις άκρων Μsk5 αναγνωρισμένο Multi - αναγνώριση ανάκτησης διορθώνει αυτό, αλλά προσθέτει πολυπλοκότητα
BM25 χτυπά πυκνή αναζήτηση σε σπάνιους όρους: Εάν το ερώτημά σας περιέχει τεχνικό φράγμα ή σωστές αναφορές δεν είναι καλά γνωρίζετε-προσωπεύεται στο ενσωματωμένο μοντέλοΜSK2 δεδομένα κατάρτισης, λεξική αντιστοιχίαM SK4BMMK5 θα υπερεκτερεύσει σεμάντικη αναζήτηση ΜSK6 Αυτός είναι ο λόγος για τον οποίο η υβριδική αναζήτηση έχει σημασία .
OCR σκουπίδια σε σαρωμένα PDFs: Το Docling είναι καλόΤο , αλλά τα σφάλματα του OCR συνδέονται με το . Αν δείτε ανοησία στα σύνολαΤο , ελέγξτε την παραγωγή από το Docling πρώτα Το - ο συνοψιστής μπορεί να επιτύχει το ' η εισαγωγή απορριμμάτων
Οι συνοπτικές εκτιμήσεις χαμηλού επιπέδου - πρέπει να καλύπτουν τη γλώσσα: Εάν ενδιαφέρεστε το ' αναφέρει μόνο βλέποντας ΜSK2 αναφέρουν από ένα έγγραφο ΜSK3 αναφέρουν φράσεις όπως " αναφέρθηκε αμέσως στο " αναφέρει ή Το " διατηρεί συμπεράσματα Η " αναφέρει ότι είναι άδικο η . αναφέρει πως το σύστημα πρέπει να πει Η " διατηρήσει δείκτες σε μετρητά της " αναφέρει και αποφεύγει οριστικούς τερματισμούς
Ετικέτες hallucination: Μικρά LLMs ΜSK1B-3B παραμύθιαM SK3 μερικές φορές εφευρέσει αξιόπιστηMK4αξιολογημένες αναφορές.Εμείς επικυρώνουμε παρτίνιζοντας την παραγωγή για [chunk-N], ειδήσεις επαλήθευσης N υπάρχει στα κομμάτια πηγής ειδήσεις, και σηματοδότηση ή επισκευή αξιώσεις που αναφέρουν λείπουν κομμάτι ειδήσεις . ειδήσεις Αν δείτε [chunk-999] για ένα 10-chunk έγγραφο, το LLM σας αγωνίζεται με την εργασίαM SK2
Αυτά είναι'τ bugs ΜSK1τ 'τ κληρονομικές εντάσεις στο χώρο σχεδιασμού.Τα καλά συστήματα παραγωγής αναγνωρίζουν και τα ελαχιστοποιούν
Κατά την επεξεργασία πολύ μεγάλων εγγράφων,Το DocSummarizer δεν ενδιαφέρει το ' προσπαθεί να ενσωματώσει τα πάντα Το - χρησιμοποιεί σεμάντικη προΜSK3φιλτράρισμα για να επιλέξει αντιπροσωπευτικά τμήματαΗ . Αυτό σημαίνει ότι η περίληψη βασίζεται σε δείγμα, όχι το πλήρες έγγραφο.
Το σύστημα διαχειρίζεται αυτό με διαφάνεια:
// If coverage is low (<5%), prepend disclaimer and use cautious language
if (coverage < 0.05)
{
var disclaimer = $"WARNING: Summary (sampled ~{coverage:P1} of document)";
summary = $"{disclaimer}\n\n{CleanAndHedge(summary)}";
}
// Append coverage footer to every summary
var footer = $"\n\n---\nCoverage: {coverage:P1} ({scope})\nConfidence: {confidence}";
Σημαντικό: Αυτό είναι ένα Σύνοψη των αποδεκτών στοιχείων, δεν εγγυάται την πλήρη κάλυψη του εγγράφου - ΜSK2 Όταν λέμε ΜSK3 Σύνδεσμοι 3%", ότι Η ' αναφέρει ακριβώς τι συνέβη η - το σύστημα είδε Η 3% από το έγγραφο και συνοψίστηκε ότι ο .
Η δειγματοληψία δεν έγινε τυχαία - ανέφερε ότι ανέφερε' ανέφερε Σεμάντικα. Χρησιμοποιούμε πολλαπλές κλάσεις - για να διασφαλίσουμε ότι τα θέματα μειοψηφίας είναιΜSK2 εξαιρούνται ΜSK3 Ένας τυχαίος Μσκ4 θα μπορούσε να χάσει όλα τα περιοριστικά και περιθώρια περιστατικών ΜСК5 Μια σημαντική Μσκ6 προσπαθεί να συλλάβει ένα αντιπροσωπευτικό τμήμα από κάθε κύριο θέμα ΜΣΚ7 Σχεδόν ΜSK8 εξακολουθεί να έχει μερική κάλυψη ΜΚ9 αλλά αυτό σημαίνει ΜSK10 εν προκειμένω διαφοροποιημένη μερικής κάλυψης
Προσαρμοστικό δείγμα με πολλαπλές ερεθίσματα θεμάτων: Το προειδοποιητικό φίλτρο - χρησιμοποιεί πολλαπλές ερεθίσματα ΜSK2μεταξύ-μετάξύ-στυλ κλουστοποίηση ενός στρωμένου δείγματος) για να εξασφαλιστεί ότι τα θέματα μειοψηφίας είναιM SK6 συστηματικά αποκλείεταιMK7Αυτό εμποδίζει το ΜSK8κυνητικές θεματικές παραμέτρους" όπου ένα ενιαίο κεντρικό κάτωM Sk10μετοξύ σημαντική
Από SegmentExtractor.cs:
// Multi-anchor approach prevents single-centroid bias
var topicAnchors = ComputeTopicAnchors(embeddedSample, k: 5);
// Score by max similarity to ANY anchor (catches minority topics)
var score = topicAnchors.Max(anchor => CosineSimilarity(segment.Embedding, anchor));
Αυτή είναι η έρευνα-informed ΜSK1eviding single-query αναμνηστική κατάρρευσηM SK3 αλλά πρακτικό MSKA4 τρέχει σε δευτερόλεπτα στο CPUMKA5
Γιατί όχι μόνο ενσωματώνουν τα πάντα?
Για ένα 500- αναλυτικό έγγραφο ΜSK1 αναλυτικά τμήματα Η ), ενσωματώνει τα πάντα θα λειτουργούσαν, αλλά δεν είναι βέβαιο ότι η ' εξασφαλίζει το καλύτερο
Η πολλαπλή δειγματοληψία - σας παρέχει το καλύτερο από τις δύο ειδήσεις: ειδικά ευρεία κάλυψη θέματος με ιχνηλαστή υπολογιστή ειδικά. ειδικά
Αυτό που μου άρεσε've περιγράφεται παραπάνω δεν είναι't μόνο M SK2retrieval" ΜSK4 ότιMK5t ένα συγκεκριμένο πρότυπο καλούμε Εξέγερση Fuzzy Context Dragging (CFCD). Η εικόναΜSK1
Οι περισσότεροι συνοψιστές συνεχίζουν να προσθέτουν το πλαίσιο. DocSummarizer Πήγαινε μπροστά Μόνο αυτό που επιβιώνει καθοριστική επιλογή, στη συνέχεια αφήνει το μοντέλο να γράψει ομαλά μέσα σε εκείνα τα όριαΜSK1
Εδώ' αναφέρει πώς οι χάρτες του σωλήνα DocSummarizer σε CFCD:
| CFCD Σχεδιασμός | DocSummarizer Implementation ΜSK2 |
|---|---|
| Αποκάλυψη Salience (fuzzy) ΜSK2 Ενσωμάτωσης ΜSK3 κεντροειδής ομοιότητας , TF Μ SK5IDF κεντρικότητα ΜΚ6 | |
| Αποτελεσματική προώθηση | MMR , BM ΜSK2 RRF συγχώνευση , κορυφαία-K επιλογή ΜSK5 |
| Άντορ Λέγκερ | Το ανακτημένο τμήμα που περιλαμβάνει τα αναγνωριστικά αναφοράς ΜSK1 |
| Η περιορισμένη γενιά | Σύνθεση σύντομα συνδέεται με αποδεκτά στοιχεία ΜSK1 |
Γιατί αυτό έχει σημασία: Το μοντέλο δεν μετράει' αποφασίζει τι μετράται' σχετικό ΜSK3 ο σωλήνας ανάκτησης ευνοεί. Το πρότυπο παράγει μόνο ρευστά εντός των συνόρων που αγαπάμε' εγκαθιδρύθηκε. Αυτός είναι ο λόγος για τον οποίο μικρά τοπικά μοντέλα λειτουργούν ΜSK7 οι ανδρείες κάνουν τη βαριά αναρρίχηση .
Το "anchor ledgerM SK1 στην πράξη μοιάζει με αυτό ΜSK2conceptually):
{
"coverage": "3.2% semantic sample",
"anchors": [
{ "id": "chunk-12", "text": "Reset requires holding button 10s", "salience": 0.92 },
{ "id": "chunk-45", "text": "Factory reset clears all settings", "salience": 0.88 }
],
"constraints": {
"terms": { "factory reset": "restore factory settings" },
"hedging": "sampled 3% - avoid definitive conclusions"
}
}
Στη συνέχεια, στη σύνθεση έλαβε το :
Αυτός είναι ο λόγος για τον οποίο η :
Το CFCD είναι η ίδια φιλοσοφική διαίρεση με Περιορισμένη ψευδαίσθηση, Ετικέτες Fuzzy MoM, επιχειρήσεις και Φωτογραφία Summarizer - πιθανότητα προτείνειΜSK1 καθορισμός εξακολουθεί Η - εφαρμόστηκε κατά τη διάρκεια του χρόνουΗ ΜSK3 αναμνηστικό άξοναη ΜSK4
Τα μοντέλα ONNX μπορούν να ποσοτικοποιηθούν ( με μειωμένη ακρίβειαΜSK1 για μικρότερο μέγεθος και γρηγορότερη παραπομπή ΜSK2 Το εμπόριο -off είναι ελάχιστη απώλεια ποιότητας
| μοντέλο ΜSK1 Πλήρης ακρίβεια ΜSK2 Κβαντισμένο | Διαφορά ποιότητας |
|---|---|
| όλοιΜSK1MiniLM-Μ SK3MK4 ΜSK5 ΜΚ6MB ΜΣΚ7 23MB | |
| bge -small-M SK3vMK4 ΜSK5 □133MB ΜSK7 ─34MB |
Για τα μεγάλα έγγραφα, ειδικά το , είναι κρίσιμο για τις επιδόσεις του . ειδικά ο ONNX Runtime ειδικά η ' αναφέρει InferenceSession Μπορεί γενικά να μοιράζεται σε διάφορες γραμμές με ασφάλεια για τις επιχειρήσεις , αλλά η απόδοση εξαρτάται από τη ρύθμιση της συνεδρίας για τις εταιρίες :
public async Task<float[][]> EmbedBatchAsync(IEnumerable<string> texts, CancellationToken ct)
{
var textList = texts.ToList();
var results = new float[textList.Count][];
// InferenceSession is safe to share for inference in most cases
// Tune SessionOptions.IntraOpNumThreads and InterOpNumThreads for your workload
var maxParallel = Math.Min(Environment.ProcessorCount, 8);
await Parallel.ForEachAsync(
textList.Select((text, index) => (text, index)),
new ParallelOptions { MaxDegreeOfParallelism = maxParallel },
async (item, token) =>
{
results[item.index] = await EmbedSingleAsync(item.text, token);
});
return results;
}
Τίτλος επιδόσεων: Προσαρμογή SessionOptions Όταν δημιουργείται η συνεδρίαση:
var sessionOptions = new SessionOptions
{
IntraOpNumThreads = 4, // Threads within a single operation
InterOpNumThreads = 2 // Threads across operations
};
var session = new InferenceSession(modelPath, sessionOptions);
Πολύ μεγάλα έγγραφα (novelsΜSK1 νόμιμα έγγραφοΗ ) απαιτεί ειδική μεταχείριση για να αποφευχθεί η OOMη :
// For documents > MaxSegmentsToEmbed, use hierarchical extraction
if (segments.Count > _config.MaxSegmentsToEmbed)
{
// Process in batches, keeping only top-K per batch
// Then re-rank globally
return await ExtractHierarchicalAsync(segments);
}
Real-world επιδόσεις σε μια τυπική μηχανή προγραμματιστή ΜSK1Ryzen M SK2X, ΜSK4GB RAMMSKA5 δεν υπάρχει GPUMKA6
| Δραστηριότητες ΜSK1 Διαδίκτυο ΜSK2 Σημειώσεις | |
|---|---|
| Ενσωμάτωση | ΜSK1 segments/sec ΜSK3 μεγέθους μπάτσου 64, όλαMK5MiniLMM SK6Μσκ7Mσκ8 ποσοτικοποιημένο |
| Δύσκολη απόσυρση | ΜSK1ms ΜSK2 Συνομοσύνη Cosine πάνω 500 segments |
| Η ΜΜΣΑΔΕ ΑΥΤΟΚΙΝΗΤΑΙ | ΜSK1μς ΜSK2Σε - μνήμη αναστρέψιμος δείκτης |
| RRF συγχώνευση | ΜSK1ms ΜSK2 Combine 3 βαθμολογίες |
| Τελικά-toΜSK1end M SK2page PDF) | Η ΜΣΚ1Επιφέρει ΜΣΚ2Περιλαμβάνει κουνάρισμαΗ MΣΚ3ενσωμάτωσηΗ ,ανακάλυψηΗ Σύνθεση LLMη ΜΣΚΑ6 |
Περιβάλλον δοκιμών: Ryzen 5600X ΜSK2core), ΜSK4GB RAMMK5 καμία GPU. Embedding χρησιμοποιεί όλαM SK7MiniLMM Sk8LMesk9Mosk10(μετρημένα,SSK13Token maxSMK14SS8-Tread παράλληλη συσκευασίαSmK16Retrieval corpusS:SSC18 segmentsMSC19Το δευτερόλεπτο σας θα ποικίλει με διαφορετικά μοντέλαMS,hardwareS, και πολυπλοκότητα εγγράφου
Ο κύριος οδηγός είναι ενσωματωμένος διαδρομή ( επιχειρηματικό μοντέλο επιλογή ΜSK1 μήκος token ΜSK2 μεγέθους μπάτσου ). Retrieval και συγχώνευση είναι βασικά δωρεάν - παίρνουν εκατομμύρια δευτερόλεπτα MK5 Αυτό ενισχύει το MC6LLM τελευταία UC7 αρχή EC8 κάνει φθηνή εργασία CPU IC9 εκμετάλλευσης NC10 ανακάλυψης CS11 πρώτος CC12 δαπανηρή LLM εργασία μόνο σε φίλτρα περιεχόμενο UC13
Σκάλινγκ: Η ιεραρχική εξόρυξη χειρίζεται ΜSK1 σελίδες έγγραφα ΜSK2novels , εγχειρίδια ΜΚ4 με επεξεργασία σε συσκευές και διατηρώντας μόνο κορυφαία ΜΣΚ5K ανά συσκευή στη μνήμη ΜСК6
Το DocSummarizer αποδεικνύει ότι οι εξελιγμένες ικανότητες NLP δεν επιτυγχάνουν το ' απαιτούν cloud APIs ή Python εξαρτήσεις. Με ONNX Runtime για ενσωμάτωση και Ollama για γενιά, μπορείτε να χτίσετε ένα ολοκληρωμένο σωλήνα RAG που επιτύχει:
Τα βασικά στοιχεία από την κατασκευή αυτού του εργαλείου:
Αυτό καταλήγει στο συμπέρασμα της σειράς DocSummarizer. Εδώ' αναφέρει πώς τα τρία μέρη ταιριάζουν μαζίM SK2
ΕΠΙΧΕΙΡΗΣΗ 1 εξηγήσεις Γιατί Η προσέγγιση του σωλήνα χτυπά άγρια κλήσεις LLM.Αυτή καλύπτει τα αρχιτεκτονικά πρότυπα (chunkingM SK2 ιεραρχική μείωσηMK3 επικύρωση αναφοράςΜSK4 που κάνει οποιοδήποτε σύνολο εγγράφου λειτουργεί καλάMST5Το εργαλείο εξελίχθηκε από τότε το μέρος ΜσΚ6 γράφτηκεΜΣΚ7 αλλά οι αρχές παραμένουν έγκυρεςMSC8
ΕΠΙΧΕΙΡΗΣΗ 2 Είναι ο γρήγορος οδηγός εκκίνησης -.ΕγκατάστασηΜSK2Modes, πρότυπαM SK4 κοινές περιπτώσεις χρήσηςMSKA5Αν θέλετε απλά να χρησιμοποιήσετε το εργαλείοMKA6 ότιMK7 όλα όσα χρειάζεστε
ΕΠΙΧΕΙΡΗΣΗ 3 (Αυτό το άρθροΜSK1 είναι η βαθιά κλίση για τους ανθρώπους που θέλουν να κατανοήσουν Πώς πράγματι λειτουργεί: BERT vs φράση μετασχηματιστές , γιατί το ONNX έχει σημασία, tokenization gotchasM SK3 υβριδική εμπορία αναζήτησης ΜSK4ΜSK5 και τι διακοπές στην παραγωγή
Εάν σας αρέσει' αναφέρει την κατασκευή του δικού σας σωλήνα, αναφέρεται να διαβάζετε όλα τα τρίαΜSK2 αναφέρθηκε Αν σας αρεθεί' αναφέρει απλά χρησιμοποιώντας το εργαλείο, αναφέρει ανάγνωση Μέρος M SK5 αναφέρει και ίσως σχήμα Μέρος
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.