Summary
In build_rag_database.py, the variable idx is used for two different purposes inside the same loop: first as the per-caption enumeration index, and later as a crop-start offset inside the motion-cropping branch. For any caption whose motion is at least max_motion_length (224) frames long, idx is overwritten to 0 before the entry's motion_id is built. All such captions of the same motion are therefore written to the database under the identical id "{name}_0", instead of one id per caption.
Affected code
- Caption enumeration:
|
for idx, line in enumerate(lines): |
idx overwritten in the cropping branch:
|
max_motion_length = cfg.dataset.max_motion_length # 224 |
|
if m_length >= max_motion_length: |
|
idx = 0 |
|
motion = motion[idx : idx + max_motion_length] |
- Overwritten value used to build the id:
|
motion_ids.append(f"{name}_{idx}") |
for idx, line in enumerate(lines): # idx = per-caption index
...
max_motion_length = cfg.dataset.max_motion_length # 224
if m_length >= max_motion_length:
idx = 0 # <-- clobbers the outer idx
motion = motion[idx : idx + max_motion_length]
m_length = max_motion_length
...
motion_ids.append(f"{name}_{idx}") # uses the clobbered value
Expected vs actual behavior
- Expected: each (motion, caption) pair gets a unique
motion_id of the form "{name}_{caption_index}", as the non-cropping branch produces.
- Actual: whenever the cropped clip length reaches 224 frames, every caption of that motion is stored under
"{name}_0", regardless of its actual caption index. motion_ids.npy then contains duplicate ids pointing at different captions/embeddings.
Steps to reproduce
- Run
build_rag_database.py on HumanML3D per the README.
- Load
database/motion_ids.npy and count duplicates:
import numpy as np
ids = np.load("database/motion_ids.npy")
print(len(ids), len(set(ids.tolist()))) # second number is smaller: duplicate ids exist
- Inspect any motion whose raw clip is >= 224 frames and has multiple captions: all of its rows carry the
_0 suffix.
Impact
Any consumer that treats motion_id as a unique key for a (motion, caption) pair (deduplication, per-caption alignment with a second array, sampling, counting) silently merges or overwrites distinct entries for long motions. Since 224 frames (~11.2 s at 20 fps) is a common HumanML3D clip length, this affects a substantial fraction of the database rather than a rare edge case.
Summary
In
build_rag_database.py, the variableidxis used for two different purposes inside the same loop: first as the per-caption enumeration index, and later as a crop-start offset inside the motion-cropping branch. For any caption whose motion is at leastmax_motion_length(224) frames long,idxis overwritten to0before the entry'smotion_idis built. All such captions of the same motion are therefore written to the database under the identical id"{name}_0", instead of one id per caption.Affected code
ReMoMask/build_rag_database.py
Line 152 in 00499c3
idxoverwritten in the cropping branch:ReMoMask/build_rag_database.py
Lines 174 to 177 in 00499c3
ReMoMask/build_rag_database.py
Line 235 in 00499c3
Expected vs actual behavior
motion_idof the form"{name}_{caption_index}", as the non-cropping branch produces."{name}_0", regardless of its actual caption index.motion_ids.npythen contains duplicate ids pointing at different captions/embeddings.Steps to reproduce
build_rag_database.pyon HumanML3D per the README.database/motion_ids.npyand count duplicates:_0suffix.Impact
Any consumer that treats
motion_idas a unique key for a (motion, caption) pair (deduplication, per-caption alignment with a second array, sampling, counting) silently merges or overwrites distinct entries for long motions. Since 224 frames (~11.2 s at 20 fps) is a common HumanML3D clip length, this affects a substantial fraction of the database rather than a rare edge case.