Nodes/Computational LSNet/Text / txt → Vector
ComfyUI Node

Text / txt → Vector

Reading a Vector Back Off Disk (And Why Your Loop Kept Reading the Old One)

By let-the-name-be-x1·Created 24 days ago·Updated 24 days ago· 2
Text / txt → Vector
  • trigger
  • vector
  • report
◄modeauto►
◄text►
◄file►
◄dtypefloat32►
◄on_missingerror►

Saving a style vector you liked is useless if you can't get it back. This is the other half of Vector → Text / txt: give it a string or a filename, get a TENSOR, and hand it to the classifier to read the artist names back out.

That round trip is the whole archive feature. The author's numbers on it: 2048 dims, thousands of values, 0.00e+00 error for plain/comma/lines/b64, and a stored-then-loaded vector that classifies identically to the original.

It also does the less obvious job: it's the bridge that makes caching loops work, which is how the pack's genetic-algorithm workflow carries a vector population from one Queue press to the next.

Inputs

mode is the only required one: auto (default), plain, comma, json, b64, lines. In auto it sniffs the content - a b64: prefix means base64, a leading [ means JSON, anything else is treated as plain separated numbers. You can leave it on auto essentially forever; force it only when you're loading something hand-edited.

Then, all optional:

  • text - paste the numbers directly. Multiline.
  • file - a filename or an absolute path. The resolution order is forgiving: absolute path first, then output/<name>, then input/<name>, and if that all fails it recursively searches up to three levels under output/ and input/ for a matching basename, taking the newest by modification time. So lsnet_vector.txt alone will find the file you saved into output/lsnet_vectors/.
  • dtype - float32 (default, and what LSNet features are), float64, float16.
  • trigger - an any-type port with one job: wire Vector → Text / txt's vector_out into it and ComfyUI will be forced to write before it reads. The engine has no concept of a file dependency between nodes; without this, a graph that saves and loads the same path can load last run's file. It's a compatibility input made of pure scheduling pain.
  • on_missing - error (default) or zeros. zeros returns a 1×1 zero vector placeholder instead of blowing up, which is the trick for "first generation of the loop has no cache yet."

Outputs: vector (TENSOR, the thing you wanted) and report (JSON: source, detected_format, numel, dtype, chars, plus a note when something was substituted).

The caching behaviour you're going to rely on

ComfyUI caches node outputs aggressively and re-runs only what it thinks changed. A loader that blindly read a file once would hand you the same tensor for the rest of the session, because from the engine's point of view nothing on its inputs moved. This node dodges that with an IS_CHANGED that returns the resolved path plus the file's mtime_ns and size - so when your loop overwrites the cache file, the node notices and re-reads it. That's the mechanism behind iteration loops that append a generation each Queue press.

Worth knowing the flip side, because it looked like a bug to me until I read the workflow: the pack's genetic-algorithm graph deliberately leaves trigger unconnected, so the read happens before the write and it picks up the previous generation's cache. That's intended semantics, not a wiring mistake. Leave trigger empty when you want the previous cycle's data; connect vector_out when you want this cycle's.

Install

cd ComfyUI/custom_nodes
git clone https://github.com/let-the-name-be-x1/Computational-LSNet.git
# restart ComfyUI; category "Computational LSNet"

Zero Python dependencies - empty requirements.txt, dependencies = [] in pyproject.toml, deliberately, so Manager never pip-installs a torch that replaces your CUDA build. In Manager, search Computational LSNet (or comfy node install computational-lsnet once it's in the Registry).

Like the rest of the pack's text and math half, this node needs no model. What needs the model is everything upstream and downstream of the vector: spawner1145/comfyui-kaloscope, legacy branch (Manager's lsnet 1.0.8 - the 2.0 line), with models/lsnet/kaloscope2.0/ containing best_checkpoint.pth (≈2.94 GB), class_mapping.csv and config.json.

Troubleshooting

FileNotFoundError. Read the message - it lists everywhere it looked. Usually it's the wrong root (saves go to output/, default subfolder lsnet_vectors) or a stale filename. An absolute path always works.

Your vector reads back wrong and it's suspiciously full of zeros. Non-b64 text containing ... or nan gets those tokens turned into 0, and the report says so in its note field. This is aimed squarely at people who copied an abbreviated tensor([...]) printout out of a console - that text is not recoverable. Always save through Vector → Text / txt in b64 if exactness matters; the read side will then restore both values and shape.

A shape surprise. b64 restores the stored shape: a file holding an (8, 2048) population comes back as a matrix, while the flat formats come back flat. If something downstream complains about dimensions, check the report's numel and the format before assuming the node is broken.

CategoryComputational LSNet

Inputs (6)

NameTypeDefaultDescription
modeCOMBOauto6 options: auto, plain, comma, json, b64, lines
textoptSTRING—
fileoptSTRINGtxt 文件名或绝对路径;例如 lsnet_vectors/lsnet_vector.txt
dtypeoptCOMBOfloat323 options: float32, float64, float16
triggeropt*把 Vector → Text 的 vector_out 接进来:ComfyUI 不知道文件依赖,这样做才能保证先保存再读取
on_missingoptCOMBOerror文件还不存在时:error 直接报错;zeros 返回一个 1×1 的零向量占位(用于“第一轮还没有缓存”的循环工作流)

Outputs (2)

NameTypeDescription
vectorTENSOR—
reportSTRING—