SIGLA: ΠΠΎΠΊΠ°Π»ΡΠ½Π°Ρ ΡΠΈΡΡΠ΅ΠΌΠ° ΠΏΠ°ΠΌΡΡΠΈ Π΄Π»Ρ ΠΠβΠ°Π³Π΅Π½ΡΠΎΠ² (Windows/Linux/macOS)
SIGLA β ΡΡΠΎ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ Π»ΠΎΠΊΠ°Π»ΡΠ½Π°Ρ, ΠΊΡΠΎΡΡΠΏΠ»Π°ΡΡΠΎΡΠΌΠ΅Π½Π½Π°Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° Π΄Π»Ρ Π±ΡΡΡΡΠΎΠ³ΠΎ ΠΏΠΎΠΈΡΠΊΠ° ΠΏΠΎ Π²Π΅ΠΊΡΠΎΡΠ°ΠΌ ΠΈ Π΄ΠΎΠ»Π³ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΏΠ°ΠΌΡΡΠΈ ΠΠβΠ°Π³Π΅Π½ΡΠΎΠ². Π―Π΄ΡΠΎ ΡΠΎΡΡΠΎΠΈΡ ΠΈΠ· ΠΈΠ½Π΄Π΅ΠΊΡΠ° HNSW Ρ Π½Π°Π΄ΡΠΆΠ½ΡΠΌ NumPyβΡΠΎΠ»Π±ΡΠΊΠΎΠΌ ΠΈ ΠΏΠ΅ΡΡΠΈΡΡΠ΅Π½ΡΠ½ΠΎΠ³ΠΎ Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ° Π½Π° SQLite+FTS5. ΠΡΠ΅ ΡΡΠΆΡΠ»ΡΠ΅ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ Π²ΡΠ½Π΅ΡΠ΅Π½Ρ Π² ΠΎΠΏΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΠ΅ Β«extrasΒ», ΠΏΠΎΡΡΠΎΠΌΡ Π±Π°Π·ΠΎΠ²Π°Ρ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠ° Π»ΡΠ³ΠΊΠ°Ρ ΠΈ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π±Π΅Π· ΠΈΠ½ΡΠ΅ΡΠ½Π΅ΡΠ° ΠΈ Π±Π΅Π· GPU.
# Π£ΡΡΠ°Π½ΠΎΠ²ΠΊΠ° (ΠΌΠΈΠ½ΠΈΠΌΡΠΌ)
pip install .
# ΠΠΏΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎ: HTTPβΡΠ΅ΡΠ²Π΅Ρ ΠΈ API
# pip install .[server]
# ΠΠ΅ΠΊΡΠΎΡΠ½ΡΠΉ ΠΈΠ½Π΄Π΅ΠΊΡ (HNSW Ρ ΡΠΎΠ»Π±ΡΠΊΠΎΠΌ Π½Π° NumPy)
python -c "
import numpy as np
from sigla.vector import HnswIndex
# Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΈΠ½Π΄Π΅ΠΊΡ ΠΈ Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ Π²Π΅ΠΊΡΠΎΡΡ
index = HnswIndex(dim=768)
vectors = np.random.randn(10000, 768).astype(np.float32)
index.add(vectors)
# ΠΠΎΠΈΡΠΊ Π±Π»ΠΈΠΆΠ°ΠΉΡΠΈΡ
ΡΠΎΡΠ΅Π΄Π΅ΠΉ
query = np.random.randn(768).astype(np.float32)
labels, distances = index.search(query, k=10)
print(f'ΠΠ°ΠΉΠ΄Π΅Π½ΠΎ {len(labels[0])} ΡΠΎΡΠ΅Π΄Π΅ΠΉ')
"
ΠΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΡ Π·Π°Π²ΠΈΡΠΈΡ ΠΎΡ Π΄Π°Π½Π½ΡΡ
ΠΈ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΡ. ΠΡ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅ΠΌ ΡΠ΅ΡΡΡ ΠΈ ΡΠΊΡΠΈΠΏΡΡ Π±Π΅Π½ΡΠΌΠ°ΡΠΊΠΎΠ², Π½ΠΎ Π½Π΅ Π·Π°ΡΠ²Π»ΡΠ΅ΠΌ ΡΠΈΠΊΡΠΈΡΠΎΠ²Π°Π½Π½ΡΠ΅ Β«xβΡΠ°Π· Π±ΡΡΡΡΠ΅Π΅Β» Π±Π΅Π· ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ°. ΠΠ»Ρ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ benchmarks/
ΠΈ nightly workflow performance.yml
.
- ΠΠ½Π΄Π΅ΠΊΡ HNSW (
hnswlib
) Ρ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈΠΌef
ΠΈ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΎΠΉ Π±Π°ΡΡβΠΏΠΎΠΈΡΠΊΠ° - Π€ΠΎΠ»Π±ΡΠΊ Π½Π° ΡΠΈΡΡΡΠΉ NumPy Π΄Π»Ρ ΠΊΡΠΎΡΡΠΏΠ»Π°ΡΡΠΎΡΠΌΠ΅Π½Π½ΠΎΡΡΠΈ (ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π±Π΅Π·
hnswlib
) - Π‘ΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΠ΅/Π·Π°Π³ΡΡΠ·ΠΊΠ° Π² ΡΠ°ΠΉΠ΄ΠΊΠ°ΡβΡΠ°ΠΉΠ»Ρ (
.hnsw
/.bin
+.meta
) Π΄Π»Ρ ΠΈΠ·Π±Π΅ΠΆΠ°Π½ΠΈΡ fileβlock Π½Π° Windows - WAL ΠΈ Π°ΠΊΠΊΡΡΠ°ΡΠ½Π°Ρ ΡΠ°Π±ΠΎΡΠ° Ρ SQLite (WAL,
PRAGMA synchronous=NORMAL
,wal_checkpoint(TRUNCATE)
) - ΠΠ½ΡΠ΅Π»Π»Π΅ΠΊΡΡΠ°Π»ΡΠ½ΠΎΠ΅ ΠΊΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π·Π°ΠΏΡΠΎΡΠΎΠ² (ΠΏΡΠΎΡΡΡΠ΅ LRU/Π±Π°ΡΡβΠΊΡΡΠΈ)
- SQLite + FTS5 Π΄Π»Ρ ΡΠ΅ΠΊΡΡΠΎΠ² ΠΈ ΠΌΠ΅ΡΠ°Π΄Π°Π½Π½ΡΡ
- ΠΠ΅ΠΊΡΠΎΡΠ½ΡΠΉ ΠΈΠ½Π΄Π΅ΠΊΡ Ρ ΡΠ°Π½ΠΈΡΡΡ ΡΡΠ΄ΠΎΠΌ ΡΠ°ΠΉΠ΄ΠΊΠ°ΡβΡΠ°ΠΉΠ»Π°ΠΌΠΈ
- ΠΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠ° ΡΠ΄Π°Π»Π΅Π½ΠΈΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² ΠΈ ΠΏΡΠΈΠΎΡΠΈΡΠ΅Ρ Β«ΡΠΎΡΠ½ΠΎΠ³ΠΎ ΡΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΡΒ» Π² Π²ΡΠ΄Π°ΡΠ΅
- ΠΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ Π·Π°ΠΌΠ΅Π½ΠΈΡΡ ΡΠΌΠ±Π΅Π΄Π΄ΠΈΠ½Π³ΠΈ Π½Π° ΡΠ²ΠΎΠΈ (ΠΎΠΏΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎ
transformers
/sentence-transformers
)
observe(text) β id
,recall(query, k) β items
,feedback(ids, reward_delta)
- Π₯ΡΠ°Π½Π΅Π½ΠΈΠ΅: SQLite+FTS5, ΠΏΠΎΠΈΡΠΊ: HNSW/NumPy, Π²ΡΡ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎ
- ΠΡΡΠΎΠΊΠΎΡΡΠΎΠ²Π½Π΅Π²ΡΠΉ ΠΌΠΎΠ΄ΡΠ»Ρ
sigla.memory.api
ΠΈ RESTβΡΠ΅ΡΠ²Π΅Ρ (FastAPI)sigla.memory.server
from sigla.memory.api import create_memory, observe_texts, recall
mem = create_memory("./agent_memory.db", dim=384)
ids = observe_texts(mem, ["text 1", "text 2"])
items = recall(mem, "query", k=5)
from sigla.cache import CachedIndex
# ΠΠ±ΠΎΡΠ°ΡΠΈΠ²Π°Π΅ΠΌ ΠΈΠ½Π΄Π΅ΠΊΡ Ρ ΠΊΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ
cached_index = CachedIndex(
base_index,
cache_backend="lru", # ΠΈΠ»ΠΈ "redis"
cache_ttl=3600.0,
max_size=10000
)
# ΠΠΎΠ²ΡΠΎΡΠ½ΡΠ΅ Π·Π°ΠΏΡΠΎΡΡ Π±ΡΠ΄ΡΡ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡΡΡ ΠΈΠ· ΠΊΡΡΠ°
labels, distances = cached_index.search(query, k=10)
index.save("./my.index") # ΡΠΎΠ·Π΄Π°ΡΡ ./my.index.meta ΠΈ ./my.index.hnsw|.bin
idx2 = HnswIndex.load("./my.index")
ΠΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³ ΠΈ ΠΏΡΠΎΠ΄Π²ΠΈΠ½ΡΡΡΠ΅ ΠΌΠ΅ΡΡΠΈΠΊΠΈ Π΄ΠΎΡΡΡΠΏΠ½Ρ ΡΠΎΠ»ΡΠΊΠΎ Π² Π²ΠΈΠ΄Π΅ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎΠ³ΠΎ ΠΏΡΠΎΡΠΈΠ»ΠΈΡΠΎΠ²Π°Π½ΠΈΡ; ΡΠ΅ΡΠ΅Π²ΡΠ΅ ΡΠΊΡΠΏΠΎΡΡΠ΅ΡΡ ΠΈ ΡΠ΅ΡΠ²ΠΈΡΡ ΠΈΡΠΊΠ»ΡΡΠ΅Π½Ρ.
# ΠΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΡ Π³ΠΈΠΏΠ΅ΡΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² Π½Π° Π²Π°ΡΠ΅ΠΌ Π΄Π°ΡΠ°ΡΠ΅ΡΠ΅
python -m sigla.auto_optimizer \
--dataset ./my_vectors.npy \
--queries ./my_queries.npy \
--output optimization_results.json
# ΠΠ΅Π½ΡΠΌΠ°ΡΠΊΠΈ
python benchmarks/runner.py --dataset sift --output benchmark_results.json
# Π‘ΠΊΠ°ΡΠΈΠ²Π°Π½ΠΈΠ΅ ΡΠ΅ΡΡΠΎΠ²ΡΡ
Π΄Π°ΡΠ°ΡΠ΅ΡΠΎΠ²
python scripts/download_bigann.py --dataset sift
# ΠΡΠΎΡΠΈΠ»ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΡΠ·ΠΊΠΈΡ
ΠΌΠ΅ΡΡ
python -c "
from sigla.profiler import global_profiler
from sigla.vector import HnswIndex
import numpy as np
index = HnswIndex(dim=128)
vectors = np.random.randn(5000, 128).astype(np.float32)
queries = np.random.randn(100, 128).astype(np.float32)
# ΠΡΠΎΡΠΈΠ»ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ
stats = global_profiler.benchmark_index_operations(index, vectors, queries)
report = global_profiler.generate_report()
print('Π‘Π°ΠΌΠ°Ρ ΠΌΠ΅Π΄Π»Π΅Π½Π½Π°Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ:', report['summary']['slowest_operation'])
"
ΠΠΎΡΡΡΠ°Ρ ΠΏΠ΅ΡΠ΅Π·Π°Π³ΡΡΠ·ΠΊΠ° ΠΈ GPUβΡΡΠΊΠΎΡΠ΅Π½ΠΈΠ΅ Π΄ΠΎΡΡΡΠΏΠ½Ρ ΠΊΠ°ΠΊ ΡΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌΡΠ΅ ΡΠ»ΠΎΠΈ; ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° ΡΠ°Π±ΠΎΡΠ°Π΅Ρ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ Π½Π° CPU.
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
RUN pip install -e .
# ΠΠ΅Π· ΠΎΡΠΊΡΡΡΡΡ
ΠΏΠΎΡΡΠΎΠ²/ΡΠ΅ΡΠ²Π΅ΡΠΎΠ² β Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° ΠΎΡΠ»Π°ΠΉΠ½
# ΠΠ°ΠΏΡΡΠΊ ΡΠ΅ΡΡΠΎΠ²
pytest -q -s
# Π Π°ΡΡΠΈΡΠ΅Π½Π½ΡΠ΅ ΡΠ΅ΡΡΡ/ΠΈΠ½ΡΠ΅Π³ΡΠ°ΡΠΈΠΎΠ½Π½ΡΠ΅ Π·Π°ΠΏΡΡΠΊΠ°ΡΡΡΡ Π² CI (ΡΠΌ. Workflows)
# ΠΡΠΎΠ²Π΅ΡΠΊΠ° ΠΊΠ°ΡΠ΅ΡΡΠ²Π° ΠΊΠΎΠ΄Π°
python scripts/verify_done.sh
SIGLA ΠΏΠΎΡΡΡΠΎΠ΅Π½ ΠΏΠΎ ΠΌΠΎΠ΄ΡΠ»ΡΠ½ΠΎΠΌΡ ΠΏΡΠΈΠ½ΡΠΈΠΏΡ:
sigla.vector
β HNSW/NumPy ΠΈΠ½Π΄Π΅ΠΊΡΡ ΠΈ ΡΠΎΡΡΠ΅Ρ; ΡΠΎΡ ΡΠ°Π½Π΅Π½ΠΈΠ΅/Π·Π°Π³ΡΡΠ·ΠΊΠ°sigla.memory.*
β ΠΌΠΎΠ΄Π΅Π»ΠΈ, Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ (Π»ΠΎΠΊΠ°Π»ΡΠ½Π°Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° Π±Π΅Π· REST)sigla.cache
β ΠΏΡΠΎΡΡΠΎΠΉ ΠΊΡΡ Π·Π°ΠΏΡΠΎΡΠΎΠ² ΠΈ Π±Π°ΡΡβΠΊΡΡsigla.vector.router
β Π°Π΄Π°ΠΏΡΠΈΠ²Π½ΡΠΉ ΡΠΎΡΡΠ΅Ρ (Ρ ΡΠΎΠ»Π±ΡΠΊΠΎΠΌ ΠΏΡΠΈ ΠΎΡΡΡΡΡΡΠ²ΠΈΠΈ FAISS)sigla.faiss_stub
β Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½Π°Ρ ΠΏΠΎΠ΄ΠΌΠ΅Π½Π° FAISS Π΄Π»Ρ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡΠ½ΠΎΠΉ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈsigla.wal
β WALβΠΎΠ±ΡΡΡΠΊΠ°sigla.advanced_monitoring
/sigla.auto_optimizer
β Π½Π΅ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΡΠ΅ ΠΌΠΎΠ΄ΡΠ»ΠΈ
# ΠΠ»ΠΎΠ½ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΈ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠ° Π΄Π»Ρ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ
git clone https://github.com/iMAGRAY/70B-1q-to-70B-lang.git
cd 70B-1q-to-70B-lang
pip install -e ".[dev]"
# ΠΠ°ΠΏΡΡΠΊ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠΉ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΠΈ
python -m sigla.auto_optimizer --dataset datasets/sift/base_1m.npy --queries datasets/sift/queries.npy
# ΠΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³ Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ½ΠΎΠ³ΠΎ ΠΏΠ»Π°Π½Π°
python scripts/render_kanban.py # Π³Π΅Π½Π΅ΡΠΈΡΡΠ΅Ρ kanban.html
MIT License - ΡΠΌ. LICENSE
- FAISS - Baseline Π΄Π»Ρ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ
- hnswlib - ΠΠ°Π·ΠΎΠ²Π°Ρ HNSW ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ
- Prometheus - ΠΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³ ΠΌΠ΅ΡΡΠΈΠΊ
ΠΠΎΡΠΎΠ²Ρ Π½Π°ΡΠ°ΡΡ? ΠΠ΅ΡΠ΅ΠΉΠ΄ΠΈΡΠ΅ ΠΊ ΡΠ°Π·Π΄Π΅Π»Ρ ΠΡΡΡΡΡΠΉ ΡΡΠ°ΡΡ.
ΠΡΡΡΡΡΠΉ ΡΡΠ°ΡΡ (Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°):
from sigla.memory.api import create_memory, observe_texts, recall, feedback
mem = create_memory("./agent_memory.db", dim=384) # SQLite+FTS5 + HnswIndex (hnswlib/NumPy)
ids = observe_texts(mem, [
"ΠΌΠ°ΡΠΈΠ½Π½ΠΎΠ΅ ΠΎΠ±ΡΡΠ΅Π½ΠΈΠ΅ ΠΈ Π½Π΅ΠΉΡΠΎΠ½Π½ΡΠ΅ ΡΠ΅ΡΠΈ",
"ΠΎΠ±Π»Π°ΡΠ½ΡΠ΅ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡ AWS ΠΈ Azure",
"Π³Π»ΡΠ±ΠΎΠΊΠΎΠ΅ ΠΎΠ±ΡΡΠ΅Π½ΠΈΠ΅ Π΄Π»Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΡΠ΅ΠΊΡΡΠ°",
])
items = recall(mem, "Π½Π΅ΠΉΡΠΎΠ½Π½ΡΠ΅ ΡΠ΅ΡΠΈ", k=5)
feedback(mem, [ids[0]], reward_delta=1.0)
(HTTP ΡΠ΅ΡΠ²Π΅Ρ ΡΠ΄Π°Π»ΡΠ½; Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° ΡΠ°Π±ΠΎΡΠ°Π΅Ρ ΠΎΡΠ»Π°ΠΉΠ½ ΡΠ΅ΡΠ΅Π· Python API)
ΠΡΠΎΠ±Π΅Π½Π½ΠΎΡΡΠΈ:
- ΠΠΎΠ»Π½ΠΎΡΡΡΡ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎ: Π±Π΅Π· Π²Π½Π΅ΡΠ½ΠΈΡ ΡΠ΅ΡΠ²ΠΈΡΠΎΠ²
- ΠΡΠΎΡΡΠΏΠ»Π°ΡΡΠΎΡΠΌΠ΅Π½Π½ΠΎ: Windows/Linux/macOS
- Π₯ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅: SQLite + FTS5; Π²Π΅ΠΊΡΠΎΡΠ½ΡΠΉ ΠΏΠΎΠΈΡΠΊ: HNSW Ρ ΡΠΎΠ»Π±ΡΠΊΠΎΠΌ Π½Π° NumPy
.[faiss-cpu]
/.[faiss-gpu]
β FAISS (ΠΏΠΎ ΠΆΠ΅Π»Π°Π½ΠΈΡ).[llm]
βtransformers
/sentence-transformers