Visual Document Retrieval
Safetensors
sentence-transformers
colpali-engine
qwen3_5
vision-language
colbert
late-interaction
multi-vector
vidore
document-retrieval
multimodal
Instructions to use tencent/EVIE-8B with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- sentence-transformers
How to use tencent/EVIE-8B with sentence-transformers:
from sentence_transformers import SentenceTransformer model = SentenceTransformer("tencent/EVIE-8B") sentences = [ "The weather is lovely today.", "It's so sunny outside!", "He drove to the stadium." ] embeddings = model.encode(sentences) similarities = model.similarity(embeddings, embeddings) print(similarities.shape) # [3, 3] - Notebooks
- Google Colab
- Kaggle
File size: 6,562 Bytes
315e4cf | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | #!/usr/bin/env bash
# Eval one trained run into runs/$RUN_NAME/eval/ (or eval/d<k>/ for Matryoshka).
# Resume by default. Full redo: EVAL_OVERWRITE=1.
set -euo pipefail
REPO="${REPO:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
EVIE_ROOT="${EVIE_ROOT:-$REPO}"
# shellcheck source=/dev/null
source "$REPO/code/shared/lib.sh"
evie_resolve_python
evie_pythonpath
evie_workdirs
unset PYTHONHOME
export PATH="$(dirname "$PYTHON"):$PATH"
PY="$PYTHON"
RUN_NAME="${RUN_NAME:?set RUN_NAME}"
mkdir -p "$LOG_DIR"
LOG_NODE="${NODE_RANK:-${RANK:-0}}"
LOG_FILE="$LOG_DIR/eval_${RUN_NAME}_node${LOG_NODE}_$(date +%Y%m%d_%H%M%S).log"
exec > >(tee -a "$LOG_FILE") 2>&1
echo "[log] $LOG_FILE"
EVAL_BATCH="${EVAL_BATCH:-8}"
EVAL_K="${EVAL_K:-1,5,10}"
EVAL_MAX_QUERIES="${EVAL_MAX_QUERIES:-0}"
EVAL_MAX_DOCS="${EVAL_MAX_DOCS:-0}"
EVAL_WORKERS="${EVAL_WORKERS:-8}"
EVAL_OVERWRITE="${EVAL_OVERWRITE:-0}"
NNODES="${NNODES:-1}"
NODE_RANK="${NODE_RANK:-${RANK:-0}}"
MASTER_ADDR="${MASTER_ADDR:-127.0.0.1}"
MASTER_PORT="${MASTER_PORT:-29501}"
EVAL_DDP_TIMEOUT_S="${EVAL_DDP_TIMEOUT_S:-21600}"
EVAL_FINALIZE_TIMEOUT_S="${EVAL_FINALIZE_TIMEOUT_S:-21600}"
evie_nccl
NPROC_PER_NODE="${NPROC_PER_NODE:-$("$PY" -c 'import torch; print(torch.cuda.device_count())')}"
if [[ -n "${MODEL_DIR:-}" ]]; then
ADAPTER_DIR="$MODEL_DIR"
else
ADAPTER_DIR="$RUNS_DIR/$RUN_NAME"
fi
HAS_LORA=0
HAS_FULL=0
[[ -f "$ADAPTER_DIR/adapter_model.safetensors" && -f "$ADAPTER_DIR/adapter_config.json" ]] && HAS_LORA=1
[[ -f "$ADAPTER_DIR/config.json" ]] && compgen -G "$ADAPTER_DIR/model*.safetensors" >/dev/null && HAS_FULL=1
if [[ "$HAS_LORA" != "1" && "$HAS_FULL" != "1" ]]; then
echo "[fatal] no LoRA adapter or full model under $ADAPTER_DIR" >&2
exit 1
fi
EVAL_BASE_MODEL="${EVAL_BASE_MODEL:-Qwen/Qwen3.5}"
if [[ "$HAS_FULL" == "1" ]]; then
EVAL_BASE_MODEL="$ADAPTER_DIR"
fi
if [[ "$HAS_LORA" == "1" ]]; then
TRAINED_ON="$("$PY" -c 'import json,sys;print(json.load(open(sys.argv[1])).get("base_model_name_or_path") or "")' "$ADAPTER_DIR/adapter_config.json" 2>/dev/null || true)"
if [[ -n "$TRAINED_ON" ]]; then
want="$(readlink -f "$TRAINED_ON" 2>/dev/null || echo "$TRAINED_ON")"
got="$(readlink -f "$EVAL_BASE_MODEL" 2>/dev/null || echo "$EVAL_BASE_MODEL")"
if [[ "$want" != "$got" ]]; then
echo "[fatal] adapter trained on $want but EVAL_BASE_MODEL=$got" >&2
exit 2
fi
fi
fi
HEAD_DIMS=""
if [[ -f "$ADAPTER_DIR/run_config.json" ]]; then
HEAD_DIMS="$("$PY" -c 'import json,sys;d=json.load(open(sys.argv[1])).get("head_dims") or [];print(",".join(str(int(x)) for x in d))' "$ADAPTER_DIR/run_config.json" 2>/dev/null || true)"
fi
if [[ -z "$HEAD_DIMS" && -f "$ADAPTER_DIR/config.json" ]]; then
HEAD_DIMS="$("$PY" -c 'import json,sys;d=json.load(open(sys.argv[1])).get("head_dims") or [];print(",".join(str(int(x)) for x in d))' "$ADAPTER_DIR/config.json" 2>/dev/null || true)"
fi
[[ -n "${EVAL_HEAD_DIMS:-}" ]] && HEAD_DIMS="$EVAL_HEAD_DIMS"
if [[ ! -f "$ADAPTER_DIR/run_config.json" ]]; then
EVAL_MVT="${EVAL_MVT:-1024}"
BIDIR="${BIDIR:-on}"
fi
EVAL_OUT_ROOT="${EVAL_OUT:-$RUNS_DIR/$RUN_NAME/eval}"
mkdir -p "$EVIE_TMP"
echo "[eval] tasks under $EVAL_ROOT"
"$PY" - <<PY
from collections import Counter
from eval import discover_tasks
tasks = discover_tasks("${EVAL_ROOT}")
print("[eval]", dict(Counter(t["dataset"] for t in tasks)), "total", len(tasks))
PY
CONTRACT_ARGS=()
[[ -n "${EVAL_MVT:-}" ]] && CONTRACT_ARGS+=(--max-visual-tokens "$EVAL_MVT" --allow-config-override)
[[ -n "${BIDIR:-}" ]] && CONTRACT_ARGS+=(--bidirectional-attention "$BIDIR" --allow-config-override)
[[ -n "${EVAL_DATASETS:-}" ]] && CONTRACT_ARGS+=(--datasets "$EVAL_DATASETS")
MODE_ARGS=(--resume)
[[ "$EVAL_OVERWRITE" == "1" ]] && MODE_ARGS=(--overwrite-output)
run_one_head() {
local head="$1" out="$2" label token ready head_args=()
label="${head:-single}"
[[ -n "$head" ]] && head_args=(--head-dim "$head")
token="${MASTER_ADDR}_${MASTER_PORT}_${RUN_NAME}_eval_${label}"
ready="$EVIE_TMP/eval_${RUN_NAME}_${label}.ready"
if [[ "$NODE_RANK" == "0" ]]; then
rm -f "$ready"
if [[ "$EVAL_OVERWRITE" == "1" && -d "$out" && -n "$(ls -A "$out" 2>/dev/null || true)" ]]; then
mv "$out" "${out}_archive_$(date +%Y%m%d_%H%M%S)"
fi
mkdir -p "$out"
printf '%s\n' "$token" > "$ready"
else
local r=""
for _ in $(seq 1 600); do
r=""
IFS= read -r r < "$ready" || true
[[ "$r" == "$token" ]] && break
sleep 1
done
[[ "$r" == "$token" ]] || { echo "[fatal] timed out waiting for rank0 eval setup"; return 2; }
fi
echo "[eval] run=$RUN_NAME head=$label nodes=${NNODES}x${NPROC_PER_NODE} batch=$EVAL_BATCH out=$out"
"$PY" -m torch.distributed.run \
--nnodes="$NNODES" --nproc_per_node="$NPROC_PER_NODE" --node_rank="$NODE_RANK" \
--master_addr="$MASTER_ADDR" --master_port="$MASTER_PORT" \
"$REPO/code/shared/eval.py" \
--base-model "$EVAL_BASE_MODEL" --adapter-dir "$ADAPTER_DIR" \
--eval-root "$EVAL_ROOT" --output-dir "$out" \
--embed-batch "$EVAL_BATCH" --num-workers "$EVAL_WORKERS" \
--ks "$EVAL_K" --max-queries "$EVAL_MAX_QUERIES" --max-docs "$EVAL_MAX_DOCS" \
--run-name "$RUN_NAME" "${MODE_ARGS[@]}" "${head_args[@]}" "${CONTRACT_ARGS[@]}"
if [[ "$NODE_RANK" != "0" ]]; then
local deadline=$((SECONDS + EVAL_FINALIZE_TIMEOUT_S))
while [[ ! -f "$out/summary.json" && "$SECONDS" -lt "$deadline" ]]; do sleep 2; done
fi
[[ -f "$out/summary.json" ]] || { echo "[fatal] summary.json missing for head=$label"; return 2; }
"$PY" - "$out/summary.json" "$label" <<'PY'
import json, sys
s = json.load(open(sys.argv[1]))
print(f"[eval][{sys.argv[2]}] status={s.get('status')} "
f"{s.get('completed_tasks')}/{s.get('expected_tasks')} headline={s.get('headline')}")
if s.get("n_failed"):
sys.exit(2)
PY
}
if [[ -z "$HEAD_DIMS" ]]; then
run_one_head "" "$EVAL_OUT_ROOT"
echo "== eval done: $RUN_NAME -> $EVAL_OUT_ROOT/summary.json =="
else
echo "[eval] heads $HEAD_DIMS"
IFS=',' read -r -a HEAD_LIST <<< "$HEAD_DIMS"
FAILED=()
for head in "${HEAD_LIST[@]}"; do
head="${head// /}"
[[ -n "$head" ]] || continue
run_one_head "$head" "$EVAL_OUT_ROOT/d$head" || FAILED+=("$head")
done
if [[ "$NODE_RANK" == "0" ]]; then
"$PY" "$REPO/code/shared/aggregate_heads.py" --eval-root "$EVAL_OUT_ROOT" --heads "$HEAD_DIMS" || true
fi
if (( ${#FAILED[@]} > 0 )); then
echo "[fatal] heads failed: ${FAILED[*]}"
exit 2
fi
echo "== eval done: $RUN_NAME -> $EVAL_OUT_ROOT/{d*,summary_heads.json} =="
fi
|