NEWAVE: интеллектуальный поиск музыки по аудио и тексту | Гайд 2026 | AiManual
AiManual Logo Ai / Manual.
02 Фев 2026 Гайд

NEWAVE: как заставить музыку искать саму себя

Пошаговый гайд по созданию системы ретривала музыки NEWAVE. Ищем треки по описанию, аудиофрагменту или настроению. Мультимодальные эмбеддинги, векторная БД, Pyt

Представьте: вы слышите в кафе обрывок мелодии, но не можете вспомнить ни названия, ни исполнителя. Или хотите найти песню, которая звучит "как дождь по крыше в четыре утра, но с бас-бочкой из техно". Традиционные метаданные (исполнитель, жанр, год) тут бесполезны. Проблема в том, что музыка — это не текст и не картинка. Это временной ряд сложных паттернов, эмоций и смыслов.

Все современные стриминги до сих пор работают на коллаборативной фильтрации ("тем, кто слушал это, понравилось то") и примитивных тегах. Это не поиск. Это угадывание.

NEWAVE — это подход, который игнорирует метаданные. Вместо этого он переводит и аудио, и текст песен в единое векторное пространство. Вы ищете словами — получаете музыку. Подставляете аудиофрагмент — находите похожие треки. Система понимает не жанры, а семантику и акустические паттерны.

Суть NEWAVE не в новой модели, а в архитектуре. Мы комбинируем проверенные инструменты 2026 года так, чтобы они понимали музыку на уровне человека, а не таблицы БД.

Из чего собирается этот музыкальный детектив

Вам понадобится три основных компонента:

  • Аудио-энкодер: превращает raw audio в вектор. Не MFCC из каменного века, а современную нейросеть, обученную на аудиозадачах.
  • Текст-энкодер: переводит текст песни (и ваш запрос) в вектор того же размера. Ключ — в едином пространстве.
  • Векторная база данных: хранит миллионы векторов и умеет искать среди них ближайших соседей за миллисекунды.

Звучит просто? Так и есть. Сложность в деталях — какие именно модели выбрать в 2026 году и как заставить их говорить на одном языке.

💡
Не пытайтесь использовать универсальные мультимодальные модели типа CLAP напрямую. Они хороши для общего понимания "звука", но плохо улавливают музыкальные нюансы — разницу между фанком и диско, эмоциональную окраску вокала. Для музыки нужна специализация.

Шаг 1: Готовим аудио — не просто режем, а понимаем

Первая ошибка — подавать в модель целый трек. Три минуты музыки содержат куплеты, припевы, бриджи, инструментальные проигрыши. Вектор усреднит всё и получится каша.

Правильно сегментировать трек на однородные участки. Для этого в 2026 году есть два рабочих подхода:

  1. Использовать модель для обнаружения смены тембра/ритма (например, развитые версии librosa или специализированные нейросети).
  2. Просто резать трек на неперекрывающиеся фрагменты по 10-15 секунд. Грубо, но работает для начала.

Каждый фрагмент нужно преобразовать в спектрограмму — картинку звука. Mel-спектрограмма — стандарт, но для музыки лучше использовать CQT (Constant-Q Transform), она лучше отражает музыкальные ноты. Разрешение 128x128 пикселей, частота дискретизации 22.05 кГц (половина от CD-качества, но для эмбеддингов хватит).

import librosa
import librosa.display
import numpy as np

def audio_to_cqt(audio_path, segment_length=15):
    """Загружаем аудио и режем на CQT-спектрограммы по segment_length секунд"""
    y, sr = librosa.load(audio_path, sr=22050)
    
    # Длина фрагмента в сэмплах
    samples_per_segment = segment_length * sr
    num_segments = len(y) // samples_per_segment
    
    spectrograms = []
    for i in range(num_segments):
        start = i * samples_per_segment
        end = start + samples_per_segment
        segment = y[start:end]
        
        # CQT спектрограмма
        cqt = librosa.cqt(segment, sr=sr, n_bins=84, bins_per_octave=12)
        cqt_db = librosa.amplitude_to_db(np.abs(cqt), ref=np.max)
        
        # Нормализуем и ресайзим до 128x128
        cqt_normalized = (cqt_db - cqt_db.mean()) / (cqt_db.std() + 1e-8)
        # ... ресайз до 128x128 (используй cv2 или PIL)
        spectrograms.append(cqt_normalized)
    
    return spectrograms

Не экономьте на частоте дискретизации ниже 22 кГц. Иначе потеряете высокие гармоники, которые критичны для различения инструментов. А mp3 128 кбит/с сожмёт всё так, что нейросеть будет учиться на артефактах сжатия.

Шаг 2: Выбираем модели — что актуально в 2026

Здесь всё изменилось за последние два года. Старые гайды предлагают VGGish или YAMNet — забудьте. Они были тренированы на аудиособытиях (лай собаки, скрип двери), а не на музыке.

Для аудио-энкодера в 2026 году есть три сильных кандидата:

Модель Плюсы Минусы Когда использовать
Jukebox-2 (OpenAI, 2025) Понимает стиль, тембр, инструментовку. Огромный контекст. Тяжёлая (миллиарды параметров). Медленная инференс. Если качество важнее скорости и есть GPU-кластер.
MusicLM-v3 (Google, 2025) Создана для музыки с нуля. Отличные эмбеддинги. Закрытая архитектура. API может быть дорогим. Для продакшена, если бюджет позволяет.
OpenL3-Large (обновлённая, 2024) Лёгкая, быстрая, открытая. Хороший баланс. Менее точная на сложных жанрах. Для старта, прототипов и ограниченных ресурсов.

Для текст-энкодера всё проще. Возьмите E5-Multilingual-v2-large (2024) или его более новую версию. Она специально обучена для текстового поиска и ретривала, поддерживает русский язык, и её эмбеддинги можно привести к размерности аудио-эмбеддингов через простой линейный слой.

Критичный момент: размерность векторов. Если аудио-модель выдаёт 512-мерные векторы, а текст-модель — 768, нужно либо обучить проекционный слой, либо сразу выбрать модели с совместимой размерностью.

Шаг 3: Готовим текст — не только слова, но и структура

Текст песни — это не статья в Википедии. Это повторяющиеся строки, рифмы, эмоциональные всплески. Просто скормить сырой текст модели — плохая идея.

Обработайте текст перед созданием эмбеддинга:

  • Удалите повторы (припевы). Оставьте уникальные строки.
  • Выделите ключевые слова, описывающие настроение: "темнота", "одиночество", "энергия", "ностальгия". Можно использовать простой RAKE или нейросетевой теггер.
  • Добавьте мета-описание: "[куплет] [грустный] [медленный] [фортепиано, струнные]". Это ручной труд, но он даёт огромный прирост качества.

Для транскрибирования текста из аудио используйте WhisperNote или его аналоги — они работают локально и не отправляют данные в облако.

# Пример подготовки текста песни для энкодера
def prepare_song_text(lyrics, metadata):
    """Объединяем текст песни с ключевыми словами"""
    # Уникальные строки (грубая дедупликация)
    lines = lyrics.split('\n')
    unique_lines = []
    seen = set()
    for line in lines:
        line_stripped = line.strip().lower()
        if line_stripped and line_stripped not in seen:
            seen.add(line_stripped)
            unique_lines.append(line)
    
    unique_text = ' '.join(unique_lines)
    
    # Ключевые слова из метаданных (можно автоматизировать)
    keywords = metadata.get('mood_tags', ['emotional', 'melancholic'])
    
    # Финальный текст для энкодера
    final_text = f"{unique_text} [Mood: {' '.join(keywords)}] [Instrumentation: piano, strings]"
    
    return final_text

Шаг 4: Строим единое пространство — магия выравнивания

Вот где происходит волшебство. У нас есть два типа векторов: от аудио и от текста. Они в разных пространствах. Нам нужно их выровнять.

Самый эффективный способ на 2026 год — контрастивное обучение. Но если у вас нет датасета из миллионов пар (аудио, текст), используйте простой, но рабочий метод:

  1. Создайте эмбеддинги для всех аудио-фрагментов и текстов песен.
  2. Обучите простую нейросеть (2-3 полносвязных слоя) предсказывать аудио-эмбеддинг по текст-эмбеддингу и наоборот.
  3. Используйте эту сеть как проектор: любой текст переводите в "аудио-подобный" вектор, любое аудио — в "текст-подобный".

Теперь поиск работает в едином пространстве. Вы вводите текст "грустный джаз с саксофоном" — система переводит его в вектор и ищет ближайшие аудио-векторы.

💡
Не пытайтесь выравнивать векторы через PCA или другие линейные методы. Связь между текстом и аудио нелинейна. Даже простая двухслойная нейросеть справится лучше.

Шаг 5: Векторная БД — где хранить миллионы песен

Если у вас меньше 10 тысяч треков, можно обойтись faiss или даже cosine similarity в numpy. Для продакшена нужна специализированная БД.

В 2026 году топ-3 выглядят так:

  • Qdrant 2.0+: лучшая для начинающих. Есть фильтрация по метаданным (год, жанр), русская документация, облачная версия.
  • Weaviate: если планируете расширяться до мультимодального RAG с изображениями и видео.
  • Pinecone

Структура коллекции в Qdrant:

from qdrant_client import QdrantClient
from qdrant_client.http import models

client = QdrantClient("localhost", port=6333)

client.recreate_collection(
    collection_name="music_embeddings",
    vectors_config=models.VectorParams(
        size=512,  # Размерность ваших эмбеддингов
        distance=models.Distance.COSINE
    )
)

# Каждая точка — фрагмент трека
points = [
    models.PointStruct(
        id=idx,
        vector=audio_embedding.tolist(),
        payload={
            "track_id": "song_123",
            "artist": "Artist Name",
            "title": "Song Title",
            "segment_start": 30,  # начало фрагмента в секундах
            "segment_end": 45,
            "text_embedding": text_embedding.tolist()  # опционально
        }
    )
    for idx, audio_embedding in enumerate(audio_embeddings)
]

client.upsert(collection_name="music_embeddings", points=points)

Шаг 6: Поиск и ранжирование — как не получить мусор

Простейший поиск — косинусная близость. Но на практике вы получите много ложных срабатываний: разные треки могут иметь похожие аккордовые прогрессии или ритмические паттерны.

Улучшаем результаты:

  1. Гибридный поиск: комбинируем векторный поиск с текстовым (по названию, исполнителю) через весовые коэффициенты.
  2. Переранжирование: первые 100 результатов из векторного поиска пропускаем через более тяжёлую модель для точного пересчёта схожести.
  3. Временное окно: если ищете по аудиофрагменту, учитывайте позицию фрагмента в треке. Интро и куплет должны весить по-разному.

Пример поиска по текстовому запросу:

def search_by_text(query_text, top_k=10):
    # 1. Получаем эмбеддинг запроса
    query_embedding = text_encoder.encode([query_text])[0]
    
    # 2. Проектируем в аудио-пространство
    audio_like_embedding = text_to_audio_projector(query_embedding)
    
    # 3. Поиск в векторной БД
    search_results = client.search(
        collection_name="music_embeddings",
        query_vector=audio_like_embedding.tolist(),
        limit=top_k * 3  # Берём больше для последующего переранжирования
    )
    
    # 4. Группируем по трекам (убираем дубли из одного трека)
    track_scores = {}
    for result in search_results:
        track_id = result.payload["track_id"]
        if track_id not in track_scores:
            track_scores[track_id] = {
                "score": result.score,
                "payload": result.payload,
                "segments": []
            }
        track_scores[track_id]["segments"].append(result)
    
    # 5. Сортируем треки по максимальному score среди их сегментов
    sorted_tracks = sorted(
        track_scores.items(),
        key=lambda x: max(s.score for s in x[1]["segments"]),
        reverse=True
    )[:top_k]
    
    return sorted_tracks

Где всё ломается: подводные камни NEWAVE

Я собрал типичные ошибки, которые превращают интеллектуальный поиск в случайный генератор:

Ошибка Последствие Как исправить
Использовать одну модель для всех жанров Классика и электроника смешиваются в кашу Обучить отдельные энкодеры для основных жанров или добавить жанр как признак
Игнорировать громкость и мастеринг Громкий поп-трек кажется похожим на тихую акустику Нормализовать громкость всех треков перед обработкой (LUFS)
Искать по целому треку Находится только самое "среднее", теряются интересные части Сегментировать и индексировать фрагменты, как описано выше
Не учитывать язык текста Русские запросы не находят англоязычные треки Использовать multilingual модели или переводить всё на один язык

Что дальше? Куда развивать систему

Базовый NEWAVE работает. Но это только начало. Дальше можно:

  • Добавить эмоциональные метки: анализировать вокал на эмоции (радость, грусть, гнев) через модели анализа речи.
  • Внедрить музыкальные признаки: темп, тональность, лад (мажор/минор) как фильтры в векторной БД.
  • Связать с генерацией: найденные треки использовать как референсы для ИИ-генерации музыки в похожем стиле.
  • Создать радиостанцию: на основе найденного трека строить бесконечный плейлист, как в VibeCast, но с учётом семантики.

Самый интересный вектор — поиск по "стилю исполнения". Вы говорите: "найди песни, которые поют так же отчаянно, как этот трек". Это требует анализа вокала отдельно от инструментала, но уже реализуемо с моделями 2026 года.

Юридический момент: индексируйте только те треки, на которые у вас есть права или которые находятся в свободном доступе. Платформы уже блокируют AI-музыку, и с поиском может быть та же история.

Главное преимущество NEWAVE перед коммерческими сервисами — прозрачность. Вы точно знаете, почему система нашла именно этот трек (посмотрите на ближайшие векторы). Вы можете подкручивать веса, добавлять фильтры, обучать на своих данных.

Через год все крупные стриминги будут использовать похожие системы. Но пока вы можете собрать свою — которая будет искать музыку именно так, как хотите вы. Не по алгоритму, а по смыслу.

P.S. Если хочется сразу поиграться с готовым решением — посмотрите Ray AI Media Player. Там уже зашиты некоторые идеи из NEWAVE, и можно понять, как это работает на практике.