A Super Easy Way to Try Similarity Search using Vald
How to deploy Vald on your k3d within 5 minutes
In this post, we’ll show a quick and easy way to perform a similarity search using Vald.
Prerequisites
Before we start, we need to install 4 tools.
- Helm: https://helm.sh/docs/intro/install/
- jq: https://stedolan.github.io/jq/
- k3d: https://k3d.io/
- kubectl: https://kubernetes.io/docs/tasks/tools/install-kubectl/
If you have Homebrew installed, you can install them by the following command.
$ brew install helm
$ brew install jq
$ brew install k3d
$ brew install kubectlSetting up a k3d cluster
Create a k3d cluster by executing the following command. It creates a cluster with 4 nodes (1 server + 3 agents).
$ k3d cluster create vald --api-port 6550 -p "8080:80@loadbalancer" --agents 3 --image=docker.io/rancher/k3s:v1.20.9-k3s1Please ensure that kubectl cluster-info returns a proper result.
$ kubectl config use-context k3d-vald
$ kubectl cluster-info
Kubernetes master is running at https://0.0.0.0:6550
CoreDNS is running at https://0.0.0.0:6550/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
Metrics-server is running at https://0.0.0.0:6550/api/v1/namespaces/kube-system/services/https:metrics-server:/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.Deploy Vald using Helm
Use Helm to deploy Vald to your k3d cluster.
$ helm repo add vald https://vald.vdaas.org/charts
$ helm install vald-cluster \
--version v1.1.0 \
--set defaults.image.tag=v1.1.0 \
--set gateway.backup.enabled=false \
--set gateway.meta.enabled=false \
--set gateway.lb.minReplicas=1 \
--set gateway.lb.hpa.enabled=false \
--set gateway.lb.ingress.enabled=true \
--set gateway.lb.ingress.host=localhost \
--set gateway.lb.ingress.annotations."ingress\.kubernetes\.io/protocol"=h2c \
--set gateway.lb.ingress.annotations."ingress\.kubernetes\.io/ssl-passthrough"="\"true\"" \
--set gateway.lb.ingress.annotations."traefik\.protocol"=h2c \
--set gateway.lb.ingress.annotations."kubernetes\.io/ingress\.class"=traefik \
--set gateway.lb.gateway_config.index_replica=3 \
--set agent.minReplicas=3 \
--set agent.resources.requests.cpu=100m \
--set agent.resources.requests.memory=100Mi \
--set agent.ngt.auto_index_check_duration=1m \
--set agent.ngt.auto_index_duration_limit=30m \
--set agent.ngt.dimension=300 \
--set agent.ngt.distance_type=l2 \
--set agent.ngt.object_type=float \
--set manager.compressor.enabled=false \
--set manager.backup.enabled=false \
--set meta.enabled=false \
vald/valdPlease wait until all components are ready on the k3d cluster. It’s ready if kubectl get pods returns Running status on all pods.
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
vald-agent-ngt-0 1/1 Running 0 70s
vald-agent-ngt-1 1/1 Running 0 54s
vald-agent-ngt-2 1/1 Running 0 41s
vald-discoverer-7f9d49dc54-zfl5s 1/1 Running 0 70s
vald-manager-index-5dd6d78d7c-qxvkq 1/1 Running 0 70s
vald-lb-gateway-6cf4548687-nqccd 1/1 Running 0 70sSimilarity Search
In this section, we’re going to try a similarity search of the common English words.
Install valdcli
valdcli is a useful application to send requests to Vald cluster. You can install it from the repository vdaas/vald-client-clj. The binaries for macOS and Linux are available.
For macOS,
$ curl -LO https://github.com/vdaas/vald-client-clj/releases/download/v1.1.0/valdcli-macos.zip
$ unzip valdcli-macos.zipFor Linux,
$ curl -LO https://github.com/vdaas/vald-client-clj/releases/download/v1.1.0/valdcli-linux-static.zip
$ unzip valdcli-linux-static.zipPlease put the executable valdcli in your PATH and confirm it shows help.
$ valdcli --helpInsert word vector data
Get an example JSON data from GitHub.
$ curl -O https://raw.githubusercontent.com/rinx/word2vecjson/master/data/wordvecs10000.jsonIt contains the word vectors for the 10000 most common English words. These vectors are generated using word2vec. Also, you can get 1000, 5000, and 25000 words datasets from the same repository.
Let’s try to insert the word vectors using valdcli stream-insert. wordvecs10000.json is a JSON file that has 10000 vectors (the format is like [{"id": "mac", "vector": [0.000001, 0.000002, ...]}]). Print the JSON by cat command and pass it to valdcli using pipe. valdcli stream-insert --json reads JSON data from stdin and inserts them into the Vald cluster.
$ cat wordvecs10000.json | valdcli -h localhost -p 8080 stream-insert --jsonAfter insertion, the index manager will detect the uncommitted vectors and send requests to the agents to create indexes. It may take a few minutes. (depending on the duration of the auto_index_check_duration)
Search similar words
After creating indexes, the agents will be ready to receive search requests. Now we’ll try to use two types of methods to search for similar words.
Search by vector
Using valdcli, you can send your requests from JSON-formatted vector data. Let’s send a search request with a vector in wordvecs10000.json file. Using jq command, you can extract a vector of the word "mac".
$ cat wordvecs10000.json | jq -c '.[] | select(.id == "mac") | .vector'
[-0.017271,-0.012576,-0.052985,0.078137,-0.05701,0.047284,-0.03823,0.048291,0.140177,0.030182,-0.111336,0.122068,0.079813,-0.109324,0.042757,0.025487,0.104629,0.035044,0.019199,-0.106642,0.003563,0.017941,0.044937,0.059357,0.015175,0.037392,0.043931,0.130116,-0.022636,0.025151,-0.028505,-0.000647,-0.041416,-0.053656,-0.023642,0.000312,0.030349,0.021295,0.017354,0.04326,0.051644,0.070759,0.022133,-0.008342,-4e-06,0.01115,-0.015845,0.083167,0.00851,0.089874,-0.033535,-0.034373,0.041583,-0.029511,-0.073777,0.056004,0.066064,-0.030685,-0.067741,0.035212,0.043931,0.04108,-0.035044,0.021965,0.054327,-0.025487,-0.044266,-0.018109,-0.128104,-0.025654,0.010564,-0.064387,-0.004485,-0.064723,-0.005911,-0.055668,-0.027163,-0.007671,0.016265,-0.005743,-0.066735,0.031355,0.01442,0.05265,0.105971,-0.158286,-0.018863,0.154261,0.040745,-0.058016,-0.078807,-0.015929,-0.002211,-0.037559,-0.012408,-0.004087,0.031355,0.093228,0.036553,-0.100605,-0.070759,0.057345,-0.01027,-0.016516,0.034876,-0.016768,-0.044937,0.07646,0.09591,-0.059357,-0.116702,-0.021379,-0.018612,0.068412,0.022972,-0.010983,-0.081826,-0.089874,-0.016516,-0.007839,-0.024984,-0.066399,-0.084508,-0.105971,0.030852,-0.1053,-0.034541,0.084844,-0.023978,-0.040577,-0.004318,0.022804,-0.118043,0.084508,-0.000922,-0.019367,0.027666,0.056004,-0.045608,0.056674,-0.017522,-0.049967,-0.002641,-0.123409,0.068076,0.010899,0.118714,-0.073442,-0.048961,-0.01551,0.004318,-0.024984,-0.063717,-0.012576,-0.009013,0.053991,-0.018109,-0.024481,-0.049297,0.012492,-0.042757,0.01442,-0.054998,0.054998,0.005198,-0.015342,0.01836,0.101276,-0.078807,-0.058016,-0.012073,0.072436,0.000482,-0.060698,-0.037056,0.079478,0.065393,0.007462,-0.012659,-0.00371,-0.006581,-0.126092,0.054662,-0.061034,-0.029008,-0.039068,0.046278,0.0332,-0.036721,-0.007084,-0.012911,-0.030182,-0.05768,-0.006204,-0.016851,0.038062,0.013414,0.032864,-0.045943,0.022133,-0.056004,-0.034038,0.002285,0.113349,0.177065,0.012492,-0.043931,-0.06204,-0.029511,0.026493,-0.024481,0.057345,-0.086521,-0.00436,-0.062375,-0.070759,-0.022469,0.020959,-0.080149,-0.121397,-0.02666,0.055668,0.067406,0.00918,-0.016265,0.037056,-0.107312,0.017019,0.02666,-0.022301,-0.043596,0.051644,-0.015845,-0.087862,-0.047955,0.025822,0.084844,-0.08149,0.001383,0.146213,-0.010731,0.013079,-0.034038,-0.103288,0.048626,0.013079,-0.08585,0.058016,0.018863,-0.024648,-0.138165,0.136152,0.059692,0.036386,0.050973,0.045943,-0.040745,0.045943,-0.061705,-0.019953,0.040577,0.021462,0.033032,0.036386,0.005994,0.072436,-0.112007,0.034709,-0.042087,-7.4e-05,0.041583,-0.034709,-0.099935,0.042757,0.027834,-0.051979,-0.021043,-0.101947,-0.046278,-0.015845,-0.019115,-0.053656,-0.048291,-0.002588,-0.031523,-0.05701,-0.082161,-0.006497,0.009138,0.070759,-0.058016,0.012408,0.031355,-0.029343,0.138835,-0.088533,-0.063717,-0.005408,-0.016768,0.040913]This is a 300-dimensional vector. It represents the feature of the word “mac”.
Using this vector, a search request can be created like the following.
$ cat wordvecs10000.json | jq -c '.[] | select(.id == "mac") | .vector' | valdcli -h localhost -p 8080 search -n 5 -e 0.1 --json | jq
[
{
"id": "mac",
"distance": 0
},
{
"id": "windows",
"distance": 0.9622495
},
{
"id": "apple",
"distance": 0.9877319
},
{
"id": "leopard",
"distance": 1.0445662
},
{
"id": "computer",
"distance": 1.1087651
}
]It returns the 5 most similar words of “mac”.
Search by ID
You can send a search request about a specific word in the index.
$ valdcli -h localhost -p 8080 search-by-id -n 10 -e 0.1 snow
[{:id "snow", :distance 0.0}
{:id "snowing", :distance 0.838368}
{:id "rain", :distance 0.86527264}
{:id "icy", :distance 0.93737966}
{:id "fog", :distance 0.95259696}
{:id "ice", :distance 0.9600457}
{:id "weather", :distance 0.98229766}
{:id "rains", :distance 0.9843779}
{:id "winter", :distance 1.0100114}
{:id "wet", :distance 1.0111399}]It returns the 10 most similar words of “snow”.
(valdcli returns EDN formatted results by default. If you set — json option, it returns JSON formatted results.)
Closing
Please delete the cluster by the following command.
$ k3d cluster delete valdIn this article, we’ve introduced an example to perform similarity search using Vald.
For more information, please visit our website.
