Google Research 的 MSEB 編碼指南:依照基準契約撰寫健全的編碼器,並在分類、聚類、檢索與分割任務中評分
In this tutorial, we work with MSEB, the Massive Sound Embedding Benchmark from Google Research, and approach it from the perspective of what a leaderboard number actually means: the evaluator surface.
We install the package and map its three layers, then write two deliberately different encoders against the framework’s own abstract base class: one that measures loudness over time and one that measures timbre, and encode a small synthetic corpus we generate in the notebook so nothing has to be downloaded.
We drive the classification, clustering, retrieval, and segmentation evaluators over those embeddings, call the metric functions directly to see what each one rewards, and finish by assembling the TaskMetadata a real submission carries.
The result is a comparison in which the two encoders trade places depending on which evaluator is asked, which is the argument for a multi-task benchmark made in numbers rather than in prose.
Copy CodeCopiedUse a different Browserimport os import sys import json import math import traceback import subprocess import numpy as np RESULTS = {} BENCH = {} def banner(title): print("\n" + "=" 78) print(title) print("=" 78) def section(name): def wrap(fn): def run(a, kw): banner(name) try: out = fn(a, kw) RESULTS[name] = out if isinstance(out, str) else "ok" return out except Exception as e: RESULTS[name] = f"SKIPPED / FAILED -> {type(e).
name}: {e}" print(f"\n[!] {name} did not complete: {type(e).name}: {e}") traceback.printexc(limit=3) return None return run return wrap banner("0.Install MSEB and map the three layers we will use") subprocess.run([sys.executable, "-m", "pip", "install", "-q", "mseb==0.1.
0"], check=True) import mseb from mseb import types, encoder as encoderlib, evaluator as evaluatorlib, metrics from mseb.evaluators import ( classificationevaluator, clusteringevaluator, retrievalevaluator, segmentationevaluator, ) print(f" mseb {mseb.version} | Python {sys.version.
split()[0]} | numpy {np.
version}") print("\n MSEB is three layers, and a benchmark run walks down them:") print(" types -> Sound, SoundEmbedding, Score, TaskMetadata: the shapes every task speaks") print(" encoder -> MultiModalEncoder: the contract YOUR model implements") print(" evaluators -> classification, clustering, retrieval, reranking, transcription, segmentation, ...
") print("\n evaluator entry points we will drive:") for module, cls in [(classificationevaluator, "ClassificationEvaluator"), (clusteringevaluator, "ClusteringEvaluator"), (retrievalevaluator, "RetrievalEvaluator"), (segmentationevaluator, "SegmentationEvaluator")]: print(f" {module.name.split('.
')[-1]:28s} {cls}") print("\n Everything below runs on CPU with no dataset download: we synthesise the audio.") We install mseb and import the three layers that a benchmark run walks down.
The types module holds the shapes every task speaks, Sound, SoundEmbedding, Score and TaskMetadata; the encoder module holds MultiModalEncoder, the contract our own model implements; and the evaluators package holds one module per task family.
We import only the four evaluators this notebook drives, because the classification, clustering, retrieval, and segmentation modules depend on nothing heavier than NumPy and scikit-learn.
In contrast, the reranking and transcription evaluators pull in Whisper and the task runner pulls in TensorFlow and apache-beam.Everything below therefore runs on a free CPU runtime with no dataset download and no accelerator.Copy CodeCopiedUse a different BrowserSR = 16000 @section("1.
The type contract: Sound, SoundEmbedding, Score") def typecontract(): t = np.arange(SR) / SR waveform = (0.5 np.sin(2 np.pi 440 t)).astype(np.float32) sound = types.Sound( waveform=waveform, context=types.
SoundContextParams(id="demo000", samplerate=SR, length=len(waveform), language="enus", text="a 440 Hz tone"), ) print(f" Sound id={sound.context.id!r} {sound.waveform.shape} @ {sound.context.samplerate} Hz" f" -> {sound.sizebytes:,} bytes") embedding = types.SoundEmbedding( embedding=np.
zeros((1, 16), dtype=np.float32), # (N, D): one utterance-level vector timestamps=np.array([[0.0, 1.0]], dtype=np.float32), # (M, 2): [start, end] in seconds context=sound.context, encodingstats=types.EncodingStats(inputsizebytes=sound.
sizebytes, embeddingsizebytes=16 * 4), ) print(f" SoundEmbedding embedding{embedding.embedding.shape} timestamps{embedding.timestamps.shape}" f" -> {embedding.sizebytes} bytes") print(f" compressionratio = {embedding.encodingstats.compressionratio:.5f}" f" ({1 / embedding.encodingstats.
compressionratio:,.0f}x smaller than the audio)") print(" N embeddings and M timestamps: M == N is frame-aligned, M == 1 is utterance-level.") print(" embedding may also hold N strings instead of vectors - step 8 uses exactly that.") score = types.
Score(metric="Accuracy", description="Overall classification accuracy", value=0.875, min=0.0, max=1.0) print(f"\n Score {score.metric}={score.value} in [{score.min}, {score.max}] :: {score.description}") for bad, why in [(dict(metric="", description="d", value=0.5, min=0.0, max=1.
0), "empty metric name"), (dict(metric="m", description="d", value=0.5, min=1.0, max=0.0), "min > max")]: try: types.Score(bad) except Exception as e: print(f" rejected at construction ({why}): {type(e).name}: {e}") return f"Sound {sound.sizebytes:,} B -> embedding {embedding.
sizebytes} B" typecontract() We start with the type contract, because every other layer is expressed in it.A Sound carries a waveform, along with SoundContextParams, the identifier, sample rate, length, language, and optional transcript, which follow the audio through the whole pipeline.
A SoundEmbedding carries an array of N embeddings and an array of M timestamp pairs, and the relation between N and M is the benchmark’s vocabulary: M equal to N means one vector per frame, while M equal to one means a single utterance-level vector, which is what our encoders produce.
EncodingStats records the input and embedding sizes and exposes compressionratio, here a thousandfold reduction from audio to vector.
A Score is a metric name, a value and its bounds, and it validates itself at construction, rejecting an empty metric name or a minimum above its maximum, so a malformed number cannot reach a leaderboard.
The embedding field also accepts N strings instead of N vectors, which is the door that step 8 walks through.Copy CodeCopiedUse a different Browserclass EnergyEnvelopeEncoder(encoderlib.MultiModalEncoder): """Baseline: average energy in nbins equal time slices.Loud/quiet, nothing about timbre.
""" def init(self, nbins: int = 16): super().init() self.nbins = nbins def setup(self): self.ready = True # a real encoder loads weights here def checkinputtypes(self, batch): for item in batch: if not isinstance(item, types.Sound): raise ValueError(f"{type(self).name} takes types.
Sound, got {type(item).name}") def encode(self, batch) -> list[types.SoundEmbedding]: out = [] for sound in batch: slices = np.arraysplit(sound.waveform.astype(np.float32), self.nbins) vec = np.array([[float(np.sqrt(np.mean(s 2) + 1e-12)) for s in slices]], dtype=np.float32) vec /= np.linalg.
norm(vec) + 1e-9 out.append(types.SoundEmbedding( embedding=vec, timestamps=np.array([[0.0, sound.context.length / sound.context.samplerate]], dtype=np.float32), context=sound.context)) return out class SpectralProfileEncoder(encoderlib.
MultiModalEncoder): """Contender: mean log-magnitude spectrum pooled into nbands bands.Describes timbre.""" def init(self, nbands: int = 16, frame: int = 512): super().init() self.nbands, self.frame = nbands, frame def setup(self): self.window = np.hanning(self.frame).astype(np.
float32) def checkinputtypes(self, batch): for item in batch: if not isinstance(item, types.Sound): raise ValueError(f"{type(self).name} takes types.Sound, got {type(item).name}") def encode(self, batch) ->
Related
相關文章

AI開始研究Physical AI:FSD級團隊亮出首版模型Simate-beta,空降RoboDojo
Simate團隊推出首款通用物理AI模型Simate-beta,據稱在RoboDojo排行榜上登頂,該模型展示記憶、長程任務與精細操作等能力。該公司成立僅三個月,核心團隊過去曾將端到端智駕模型推進至對標Tesla FSD水準。Simate從第一天起就採用AI for Physical AI的研發模式,讓AI參與研究流程,並已有MIT、加州理工等外部研究人員使用其工具。
智元第20000臺具身機器人交付長隆,首期超300臺機器人常駐樂園。
報道:2026 年,具身智能行業最難回答的問題之一,是怎麼落地。這裡的「落地」有兩層含義:一方面,機器人得有足夠穩定的量產能力,能夠真的交付出去;另一方面,交付之後還得適應具體場景,在真實環境裡持續工作。智元稱之為「部署態」,機器人開始離開發佈會和展會,進入真實的生產與服務環境。

馬斯克秀 AI 算力:計劃年底前配 110 萬張英偉達 GB300,目標約 6 個月躋身行業領先
作者:故淵 責編:故淵 評論: 9 月 25 日消息,全球首富埃隆 · 馬斯克(Elon Musk)今天(9 月 25 日)在 X 平臺發佈推文,詳細披露了旗下 SpaceXAI 公司的算力部署情況。SpaceXAI 公司旗下目前主要運營 Colossus 1 和 Colossus 2 兩大計算集群,其中 Colossus 1 包含 15 萬張英偉達 H100、5 萬張 H200 以及 3 萬張 GB200;而 Colossus 2 集群包含 11 萬張 GB200 以及 44 萬張 GB300。

中式夢核VS美國後室:AI是如何重塑公共IP,一年賺走十幾億美元的?
(停滯的日本GDP,被鬼打牆的何止是屏幕前的玩家,而是每一個日本人) 而在商業化路徑上,區別於美式的國際化路線,日本路線勝在小成本、量產、低風險,把夢核IP做成了可持續盈利的垂直品類。 韓國夢核文化的代表作《誰在門外?》,則乾脆把故事背景放到了90年代的漢城。玩家扮演一失憶且患有精神疾病的男性,被困在1990年代首爾的一間小公寓裡,要在8天內通過觀察環境細節分現實與幻,決定是開門拿藥還是吃藥壓制幻覺,堅持到第9天才能逃脫循環。韓國夢核IP的開發優勢在產業聯動性。

Meta 承認 Muse 產品設計深受 OpenClaw 啟發,但強調從零構建
作者:遠洋 責編:遠洋 評論: 9 月 24 日消息,Meta 旗下 Muse 的早期用戶一直在猜測,這款 AI 之所以表現出色,是不是因為其底層實際上採用了 OpenClaw,只是在此基礎上套了一層更加面向普通消費者的產品包裝。如今,Meta 方面表示,這種說法並非完全沒有依據。

被硅谷吹爆的Jev到底有什麼用?我們替你親手試了試
藍字計劃2026.09.24 18:39 · 來自廣東全文4900字00:00 / 12:20下一個Manus時刻?文|藍字計劃,作者|ChesterAI圈的一個“奇行種”,突然爆紅。9月15日,TypeSafe發佈了Jev。幾天後,它已經出現在Vercel、Cloudflare、LangChain、Langfuse等開發者工具裡。