Hi, thank you very much for your excellent work — it has been extremely helpful.
I applied the Kaldi GOP method to extract phoneme-level timestamps, and based on these timestamps, I further processed the SSL features as follows:
1. Use GOP-generated timestamps to segment frame-level SSL features.
2. Aggregate frame-level features within each phoneme segment into a chunk.
3. Compute the mean of each chunk as the phoneme-level SSL feature.
def extract_utterance(self, utt_id: str, wav_path: str) -> np.ndarray:
"""
提取单个 utterance 的音素级特征
Args:
utt_id: utterance ID
wav_path: 音频文件路径
Returns:
(num_phonemes, target_phn_frames, feature_dim) 的特征数组
"""
# 提取帧级特征
frame_features = self._load_and_extract_features(wav_path)
# 获取该 utterance 的音素信息
if utt_id not in self.ctm_data:
print(f"Warning: {utt_id} not found in CTM file")
return np.array([], dtype=np.float32)
phones_info = self.ctm_data[utt_id]
phn_features_list = []
# 对每个音素进行池化
for phn_info in phones_info:
start_frame = self._time_to_frame_idx(phn_info['start_time'])
end_frame = self._time_to_frame_idx(phn_info['end_time'])
# 提取该音素的帧
start_frame = max(0, start_frame)
end_frame = min(end_frame, frame_features.shape[0])
if start_frame < end_frame:
phn_frames = frame_features[start_frame:end_frame]
else:
phn_frames = np.array([], dtype=np.float32).reshape(0, self.feature_dim)
# 池化
pooled = self._pool_frames(phn_frames) # mean here
phn_features_list.append(pooled)
# 堆叠所有音素特征
if phn_features_list:
phn_features = np.stack(phn_features_list, axis=0) # (num_phonemes, feature_dim)
else:
phn_features = np.array([], dtype=np.float32).reshape(0, self.feature_dim)
# Padding
padded_features = self._pad_features(phn_features)
return padded_features
However, after doing this, I found that the extracted phoneme-level features differ significantly from those you released and the performance gap is also quite noticeable.
So I would like to ask:
1. Is this chunk-mean aggregation strategy consistent with your actual implementation?
2. Did you perform any additional preprocessing steps on the SSL features before or after phoneme-level aggregation?
3. Do the neighbouring silent frames also count?
This would be extremely helpful if you could help me check these issues.
Here I attached:
• My generated CTM file on test set.
• The corresponding phoneme-level WavLM features extracted using the method above and your release on utt 000030012
feats_and_ctm.zip
Hi, thank you very much for your excellent work — it has been extremely helpful.
I applied the Kaldi GOP method to extract phoneme-level timestamps, and based on these timestamps, I further processed the SSL features as follows:
1. Use GOP-generated timestamps to segment frame-level SSL features.
2. Aggregate frame-level features within each phoneme segment into a chunk.
3. Compute the mean of each chunk as the phoneme-level SSL feature.
However, after doing this, I found that the extracted phoneme-level features differ significantly from those you released and the performance gap is also quite noticeable.
So I would like to ask:
1. Is this chunk-mean aggregation strategy consistent with your actual implementation?
2. Did you perform any additional preprocessing steps on the SSL features before or after phoneme-level aggregation?
3. Do the neighbouring silent frames also count?
This would be extremely helpful if you could help me check these issues.
Here I attached:
• My generated CTM file on test set.
• The corresponding phoneme-level WavLM features extracted using the method above and your release on utt
000030012feats_and_ctm.zip