mirror of
https://github.com/pgvector/pgvector.git
synced 2026-07-22 20:15:46 +08:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9542b5548f | ||
|
|
4af2b06dc5 | ||
|
|
880dc4d6b9 | ||
|
|
fef635c9e5 | ||
|
|
78ed8f1157 | ||
|
|
f11e4d7b20 | ||
|
|
aafdf4167d | ||
|
|
656b059258 | ||
|
|
7cf9980696 |
104
.github/workflows/build.yml
vendored
104
.github/workflows/build.yml
vendored
@@ -8,10 +8,18 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- postgres: 18
|
||||
os: ubuntu-24.04
|
||||
- postgres: 17
|
||||
os: ubuntu-24.04
|
||||
- postgres: 16
|
||||
os: ubuntu-24.04-arm
|
||||
os: ubuntu-22.04
|
||||
- postgres: 15
|
||||
os: ubuntu-22.04
|
||||
- postgres: 14
|
||||
os: ubuntu-22.04-arm
|
||||
os: ubuntu-20.04
|
||||
- postgres: 13
|
||||
os: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ankane/setup-postgres@v1
|
||||
@@ -31,3 +39,95 @@ jobs:
|
||||
sudo apt-get update
|
||||
sudo apt-get install libipc-run-perl
|
||||
- run: make prove_installcheck
|
||||
mac:
|
||||
runs-on: ${{ matrix.os }}
|
||||
if: ${{ !startsWith(github.ref_name, 'windows') }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- postgres: 17
|
||||
os: macos-15
|
||||
- postgres: 14
|
||||
os: macos-13
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ankane/setup-postgres@v1
|
||||
with:
|
||||
postgres-version: ${{ matrix.postgres }}
|
||||
- run: make
|
||||
env:
|
||||
PG_CFLAGS: -DUSE_ASSERT_CHECKING -Wall -Wextra -Werror -Wno-unused-parameter
|
||||
- run: make install
|
||||
- run: make installcheck
|
||||
- if: ${{ failure() }}
|
||||
run: cat regression.diffs
|
||||
# Homebrew Postgres does not enable TAP tests, so need to download
|
||||
- run: |
|
||||
brew install cpanm
|
||||
cpanm --notest IPC::Run
|
||||
wget -q https://github.com/postgres/postgres/archive/refs/tags/$TAG.tar.gz
|
||||
tar xf $TAG.tar.gz
|
||||
mv postgres-$TAG postgres
|
||||
env:
|
||||
TAG: ${{ matrix.postgres == 17 && 'REL_17_2' || 'REL_14_15' }}
|
||||
- run: make prove_installcheck PROVE_FLAGS="-I ./postgres/src/test/perl -I ./test/perl"
|
||||
env:
|
||||
PERL5LIB: /Users/runner/perl5/lib/perl5
|
||||
- run: make clean && $(brew --prefix llvm@$LLVM_VERSION)/bin/scan-build --status-bugs make
|
||||
env:
|
||||
LLVM_VERSION: ${{ matrix.os == 'macos-15' && 18 || 15 }}
|
||||
PG_CFLAGS: -DUSE_ASSERT_CHECKING
|
||||
windows:
|
||||
runs-on: windows-latest
|
||||
if: ${{ !startsWith(github.ref_name, 'mac') }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ankane/setup-postgres@v1
|
||||
with:
|
||||
postgres-version: 14
|
||||
- run: |
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" && ^
|
||||
nmake /NOLOGO /F Makefile.win && ^
|
||||
nmake /NOLOGO /F Makefile.win install && ^
|
||||
nmake /NOLOGO /F Makefile.win installcheck && ^
|
||||
nmake /NOLOGO /F Makefile.win clean && ^
|
||||
nmake /NOLOGO /F Makefile.win uninstall
|
||||
shell: cmd
|
||||
- if: ${{ failure() }}
|
||||
run: cat regression.diffs
|
||||
i386:
|
||||
if: ${{ !startsWith(github.ref_name, 'mac') && !startsWith(github.ref_name, 'windows') }}
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: debian:12
|
||||
options: --platform linux/386
|
||||
steps:
|
||||
- run: apt-get update && apt-get install -y build-essential git libipc-run-perl postgresql-15 postgresql-server-dev-15 sudo
|
||||
- run: service postgresql start
|
||||
- run: |
|
||||
git clone https://github.com/${{ github.repository }}.git pgvector
|
||||
cd pgvector
|
||||
git fetch origin ${{ github.ref }}
|
||||
git reset --hard FETCH_HEAD
|
||||
make
|
||||
make install
|
||||
chown -R postgres .
|
||||
sudo -u postgres make installcheck
|
||||
sudo -u postgres make prove_installcheck
|
||||
env:
|
||||
PG_CFLAGS: -DUSE_ASSERT_CHECKING -Wall -Wextra -Werror -Wno-unused-parameter -Wno-sign-compare
|
||||
- if: ${{ failure() }}
|
||||
run: cat pgvector/regression.diffs
|
||||
valgrind:
|
||||
if: ${{ !startsWith(github.ref_name, 'mac') && !startsWith(github.ref_name, 'windows') }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ankane/setup-postgres-valgrind@v1
|
||||
with:
|
||||
postgres-version: 17
|
||||
check-ub: yes
|
||||
- run: make OPTFLAGS=""
|
||||
- run: sudo --preserve-env=PG_CONFIG make install
|
||||
- run: make installcheck
|
||||
|
||||
100
README.md
100
README.md
@@ -52,8 +52,6 @@ nmake /F Makefile.win
|
||||
nmake /F Makefile.win install
|
||||
```
|
||||
|
||||
Note: Postgres 17 is not supported with MSVC yet due to an [upstream issue](https://www.postgresql.org/message-id/flat/CAOdR5yF0krWrxycA04rgUKCgKugRvGWzzGLAhDZ9bzNv8g0Lag%40mail.gmail.com)
|
||||
|
||||
See the [installation notes](#installation-notes---windows) if you run into issues
|
||||
|
||||
You can also install it with [Docker](#docker) or [conda-forge](#conda-forge).
|
||||
@@ -84,7 +82,7 @@ Get the nearest neighbors by L2 distance
|
||||
SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 5;
|
||||
```
|
||||
|
||||
Also supports inner product (`<#>`), cosine distance (`<=>`), and L1 distance (`<+>`, added in 0.7.0)
|
||||
Also supports inner product (`<#>`), cosine distance (`<=>`), and L1 distance (`<+>`)
|
||||
|
||||
Note: `<#>` returns the negative inner product since Postgres only supports `ASC` order index scans on operators
|
||||
|
||||
@@ -148,9 +146,9 @@ Supported distance functions are:
|
||||
- `<->` - L2 distance
|
||||
- `<#>` - (negative) inner product
|
||||
- `<=>` - cosine distance
|
||||
- `<+>` - L1 distance (added in 0.7.0)
|
||||
- `<~>` - Hamming distance (binary vectors, added in 0.7.0)
|
||||
- `<%>` - Jaccard distance (binary vectors, added in 0.7.0)
|
||||
- `<+>` - L1 distance
|
||||
- `<~>` - Hamming distance (binary vectors)
|
||||
- `<%>` - Jaccard distance (binary vectors)
|
||||
|
||||
Get the nearest neighbors to a row
|
||||
|
||||
@@ -237,19 +235,19 @@ Cosine distance
|
||||
CREATE INDEX ON items USING hnsw (embedding vector_cosine_ops);
|
||||
```
|
||||
|
||||
L1 distance - added in 0.7.0
|
||||
L1 distance
|
||||
|
||||
```sql
|
||||
CREATE INDEX ON items USING hnsw (embedding vector_l1_ops);
|
||||
```
|
||||
|
||||
Hamming distance - added in 0.7.0
|
||||
Hamming distance
|
||||
|
||||
```sql
|
||||
CREATE INDEX ON items USING hnsw (embedding bit_hamming_ops);
|
||||
```
|
||||
|
||||
Jaccard distance - added in 0.7.0
|
||||
Jaccard distance
|
||||
|
||||
```sql
|
||||
CREATE INDEX ON items USING hnsw (embedding bit_jaccard_ops);
|
||||
@@ -258,9 +256,9 @@ CREATE INDEX ON items USING hnsw (embedding bit_jaccard_ops);
|
||||
Supported types are:
|
||||
|
||||
- `vector` - up to 2,000 dimensions
|
||||
- `halfvec` - up to 4,000 dimensions (added in 0.7.0)
|
||||
- `bit` - up to 64,000 dimensions (added in 0.7.0)
|
||||
- `sparsevec` - up to 1,000 non-zero elements (added in 0.7.0)
|
||||
- `halfvec` - up to 4,000 dimensions
|
||||
- `bit` - up to 64,000 dimensions
|
||||
- `sparsevec` - up to 1,000 non-zero elements
|
||||
|
||||
### Index Options
|
||||
|
||||
@@ -314,7 +312,7 @@ Note: Do not set `maintenance_work_mem` so high that it exhausts the memory on t
|
||||
|
||||
Like other index types, it’s faster to create an index after loading your initial data
|
||||
|
||||
Starting with 0.6.0, you can also speed up index creation by increasing the number of parallel workers (2 by default)
|
||||
You can also speed up index creation by increasing the number of parallel workers (2 by default)
|
||||
|
||||
```sql
|
||||
SET max_parallel_maintenance_workers = 7; -- plus leader
|
||||
@@ -367,7 +365,7 @@ Cosine distance
|
||||
CREATE INDEX ON items USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
|
||||
```
|
||||
|
||||
Hamming distance - added in 0.7.0
|
||||
Hamming distance
|
||||
|
||||
```sql
|
||||
CREATE INDEX ON items USING ivfflat (embedding bit_hamming_ops) WITH (lists = 100);
|
||||
@@ -376,8 +374,8 @@ CREATE INDEX ON items USING ivfflat (embedding bit_hamming_ops) WITH (lists = 10
|
||||
Supported types are:
|
||||
|
||||
- `vector` - up to 2,000 dimensions
|
||||
- `halfvec` - up to 4,000 dimensions (added in 0.7.0)
|
||||
- `bit` - up to 64,000 dimensions (added in 0.7.0)
|
||||
- `halfvec` - up to 4,000 dimensions
|
||||
- `bit` - up to 64,000 dimensions
|
||||
|
||||
### Query Options
|
||||
|
||||
@@ -549,8 +547,6 @@ Note: If this is lower than `ivfflat.probes`, `ivfflat.probes` will be used
|
||||
|
||||
## Half-Precision Vectors
|
||||
|
||||
*Added in 0.7.0*
|
||||
|
||||
Use the `halfvec` type to store half-precision vectors
|
||||
|
||||
```sql
|
||||
@@ -559,8 +555,6 @@ CREATE TABLE items (id bigserial PRIMARY KEY, embedding halfvec(3));
|
||||
|
||||
## Half-Precision Indexing
|
||||
|
||||
*Added in 0.7.0*
|
||||
|
||||
Index vectors at half precision for smaller indexes
|
||||
|
||||
```sql
|
||||
@@ -582,24 +576,16 @@ CREATE TABLE items (id bigserial PRIMARY KEY, embedding bit(3));
|
||||
INSERT INTO items (embedding) VALUES ('000'), ('111');
|
||||
```
|
||||
|
||||
Get the nearest neighbors by Hamming distance (added in 0.7.0)
|
||||
Get the nearest neighbors by Hamming distance
|
||||
|
||||
```sql
|
||||
SELECT * FROM items ORDER BY embedding <~> '101' LIMIT 5;
|
||||
```
|
||||
|
||||
Or (before 0.7.0)
|
||||
|
||||
```sql
|
||||
SELECT * FROM items ORDER BY bit_count(embedding # '101') LIMIT 5;
|
||||
```
|
||||
|
||||
Also supports Jaccard distance (`<%>`)
|
||||
|
||||
## Binary Quantization
|
||||
|
||||
*Added in 0.7.0*
|
||||
|
||||
Use expression indexing for binary quantization
|
||||
|
||||
```sql
|
||||
@@ -622,8 +608,6 @@ SELECT * FROM (
|
||||
|
||||
## Sparse Vectors
|
||||
|
||||
*Added in 0.7.0*
|
||||
|
||||
Use the `sparsevec` type to store sparse vectors
|
||||
|
||||
```sql
|
||||
@@ -657,8 +641,6 @@ You can use [Reciprocal Rank Fusion](https://github.com/pgvector/pgvector-python
|
||||
|
||||
## Indexing Subvectors
|
||||
|
||||
*Added in 0.7.0*
|
||||
|
||||
Use expression indexing to index subvectors
|
||||
|
||||
```sql
|
||||
@@ -1121,7 +1103,13 @@ Note: Replace `17` with your Postgres server version
|
||||
|
||||
### Missing SDK
|
||||
|
||||
If compilation fails and the output includes `warning: no such sysroot directory` on Mac, reinstall Xcode Command Line Tools.
|
||||
If compilation fails and the output includes `warning: no such sysroot directory` on Mac, your Postgres installation points to a path that no longer exists.
|
||||
|
||||
```sh
|
||||
pg_config --cppflags
|
||||
```
|
||||
|
||||
Reinstall Postgres to fix this.
|
||||
|
||||
### Portability
|
||||
|
||||
@@ -1139,6 +1127,14 @@ make OPTFLAGS=""
|
||||
|
||||
If compilation fails with `Cannot open include file: 'postgres.h': No such file or directory`, make sure `PGROOT` is correct.
|
||||
|
||||
### Mismatched Architecture
|
||||
|
||||
If compilation fails with `error C2196: case value '4' already used`, make sure `vcvars64.bat` was called. Then run `nmake /F Makefile.win clean` and re-run the installation instructions.
|
||||
|
||||
### Missing Symbol
|
||||
|
||||
If linking fails with `unresolved external symbol float_to_shortest_decimal_bufn` with Postgres 17.0-17.2, upgrade to Postgres 17.3+.
|
||||
|
||||
### Permissions
|
||||
|
||||
If installation fails with `Access is denied`, re-run the installation instructions as an administrator.
|
||||
@@ -1163,6 +1159,12 @@ cd pgvector
|
||||
docker build --pull --build-arg PG_MAJOR=17 -t myuser/pgvector .
|
||||
```
|
||||
|
||||
If you increase `maintenance_work_mem`, make sure `--shm-size` is at least that size to avoid an error with parallel HNSW index builds.
|
||||
|
||||
```sh
|
||||
docker run --shm-size=1g ...
|
||||
```
|
||||
|
||||
### Homebrew
|
||||
|
||||
With Homebrew Postgres, you can use:
|
||||
@@ -1250,36 +1252,6 @@ You can check the version in the current database with:
|
||||
SELECT extversion FROM pg_extension WHERE extname = 'vector';
|
||||
```
|
||||
|
||||
## Upgrade Notes
|
||||
|
||||
### 0.6.0
|
||||
|
||||
#### Postgres 12
|
||||
|
||||
If upgrading with Postgres 12, remove this line from `sql/vector--0.5.1--0.6.0.sql`:
|
||||
|
||||
```sql
|
||||
ALTER TYPE vector SET (STORAGE = external);
|
||||
```
|
||||
|
||||
Then run `make install` and `ALTER EXTENSION vector UPDATE;`.
|
||||
|
||||
#### Docker
|
||||
|
||||
The Docker image is now published in the `pgvector` org, and there are tags for each supported version of Postgres (rather than a `latest` tag).
|
||||
|
||||
```sh
|
||||
docker pull pgvector/pgvector:pg16
|
||||
# or
|
||||
docker pull pgvector/pgvector:0.6.0-pg16
|
||||
```
|
||||
|
||||
Also, if you’ve increased `maintenance_work_mem`, make sure `--shm-size` is at least that size to avoid an error with parallel HNSW index builds.
|
||||
|
||||
```sh
|
||||
docker run --shm-size=1g ...
|
||||
```
|
||||
|
||||
## Thanks
|
||||
|
||||
Thanks to:
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
#error "Requires PostgreSQL 13+"
|
||||
#endif
|
||||
|
||||
/* Check architecture in first header */
|
||||
StaticAssertDecl(sizeof(Datum) == SIZEOF_DATUM, "Architecture mismatch");
|
||||
|
||||
extern uint64 (*BitHammingDistance) (uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 distance);
|
||||
extern double (*BitJaccardDistance) (uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 ab, uint64 aa, uint64 bb);
|
||||
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
#include "storage/lmgr.h"
|
||||
#include "utils/memutils.h"
|
||||
|
||||
#if PG_VERSION_NUM >= 180000
|
||||
#define vacuum_delay_point() vacuum_delay_point(false)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check if deleted list contains an index TID
|
||||
*/
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
#include "ivfflat.h"
|
||||
#include "storage/bufmgr.h"
|
||||
|
||||
#if PG_VERSION_NUM >= 180000
|
||||
#define vacuum_delay_point() vacuum_delay_point(false)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Bulk delete tuples from the index
|
||||
*/
|
||||
|
||||
@@ -123,6 +123,12 @@ SELECT * FROM t ORDER BY val <-> '[3,3,3]';
|
||||
[0,0,0]
|
||||
(3 rows)
|
||||
|
||||
TRUNCATE t;
|
||||
SELECT * FROM t ORDER BY val <-> '[3,3,3]';
|
||||
val
|
||||
-----
|
||||
(0 rows)
|
||||
|
||||
RESET hnsw.iterative_scan;
|
||||
RESET hnsw.ef_search;
|
||||
DROP TABLE t;
|
||||
|
||||
@@ -110,6 +110,15 @@ SELECT * FROM t ORDER BY val <-> '[3,3,3]';
|
||||
[1,1,1]
|
||||
(2 rows)
|
||||
|
||||
TRUNCATE t;
|
||||
NOTICE: ivfflat index created with little data
|
||||
DETAIL: This will cause low recall.
|
||||
HINT: Drop the index until the table has more data.
|
||||
SELECT * FROM t ORDER BY val <-> '[3,3,3]';
|
||||
val
|
||||
-----
|
||||
(0 rows)
|
||||
|
||||
RESET ivfflat.iterative_scan;
|
||||
RESET ivfflat.max_probes;
|
||||
DROP TABLE t;
|
||||
|
||||
@@ -70,6 +70,9 @@ SELECT * FROM t ORDER BY val <-> '[3,3,3]';
|
||||
SET hnsw.iterative_scan = relaxed_order;
|
||||
SELECT * FROM t ORDER BY val <-> '[3,3,3]';
|
||||
|
||||
TRUNCATE t;
|
||||
SELECT * FROM t ORDER BY val <-> '[3,3,3]';
|
||||
|
||||
RESET hnsw.iterative_scan;
|
||||
RESET hnsw.ef_search;
|
||||
DROP TABLE t;
|
||||
|
||||
@@ -59,6 +59,9 @@ SELECT * FROM t ORDER BY val <-> '[3,3,3]';
|
||||
SET ivfflat.max_probes = 2;
|
||||
SELECT * FROM t ORDER BY val <-> '[3,3,3]';
|
||||
|
||||
TRUNCATE t;
|
||||
SELECT * FROM t ORDER BY val <-> '[3,3,3]';
|
||||
|
||||
RESET ivfflat.iterative_scan;
|
||||
RESET ivfflat.max_probes;
|
||||
DROP TABLE t;
|
||||
|
||||
Reference in New Issue
Block a user