embed_trees.py 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. """把 live 分类树节点名向量化(火山 multimodal)→ scope_trees/trees_embeddings.npy。
  2. 行序与 trees_index.json 一一对应。须先跑 dump_trees.py,且能连火山。
  3. 用法:python scripts/embed_trees.py [env_file]
  4. """
  5. from __future__ import annotations
  6. import json
  7. import sys
  8. from concurrent.futures import ThreadPoolExecutor
  9. from pathlib import Path
  10. import numpy as np
  11. from core.embedding import ArkEmbedConfig, embed_text
  12. OUT = Path("scope_trees")
  13. def main(env_file: str = ".env") -> None:
  14. cfg = ArkEmbedConfig.from_env(env_file)
  15. index = json.loads((OUT / "trees_index.json").read_text(encoding="utf-8"))
  16. names = [it["name"] for it in index]
  17. n = len(names)
  18. embs: list[list[float] | None] = [None] * n
  19. def work(i: int) -> int:
  20. embs[i] = embed_text(names[i], cfg)
  21. return i
  22. done = 0
  23. with ThreadPoolExecutor(max_workers=8) as ex:
  24. for _ in ex.map(work, range(n)):
  25. done += 1
  26. if done % 100 == 0 or done == n:
  27. print(f" embedded {done}/{n}")
  28. arr = np.asarray(embs, dtype=np.float32)
  29. if arr.shape != (n, cfg.dim):
  30. raise AssertionError(f"shape {arr.shape} != {(n, cfg.dim)}")
  31. np.save(OUT / "trees_embeddings.npy", arr)
  32. print("saved", arr.shape, "->", OUT / "trees_embeddings.npy")
  33. if __name__ == "__main__":
  34. main(sys.argv[1] if len(sys.argv) > 1 else ".env")