Compose — الموسيقى وإنتاج الصوت
ثلاث وحدات تعمل على الجهاز تغطّي جانب الموسيقى وإنتاج الصوت في speech-swift، وكلّها تعمل أصلًا على Apple Silicon عبر MLX أو CoreML. MAGNeT يولّد مقاطع موسيقية مدّتها 30 ثانية انطلاقًا من موجّه نصّي. فصل المصادر (Open-Unmix) يقسّم مساراً ستيريو إلى أربعة stems (الأصوات / الإيقاع / الباس / الباقي). تحسين الكلام (DeepFilterNet3) يزيل ضوضاء الخلفية من الكلام في الزمن الحقيقي.
| الوحدة | المهمّة | الواجهة الخلفية | الإخراج | CLI |
|---|---|---|---|---|
| MAGNeT | نص ← موسيقى | MLX (INT4 / INT8) | 30 ثانية @ 32 kHz أحادي | speech compose |
| Open-Unmix | فصل الـ stems | MLX | 4 stems @ 44.1 kHz ستيريو | speech separate |
| DeepFilterNet3 | قمع الضوضاء | CoreML (Neural Engine) | 48 kHz، زمن حقيقي | speech denoise |
MAGNeT — توليد الموسيقى من النص
نقل إلى MLX Swift لنموذج MAGNeT من Meta (Masked Audio Generation with a Single Non-Autoregressive Transformer). يولّد مقاطع مدّتها 30 ثانية من موسيقى أحادية بمعدّل 32 kHz انطلاقًا من موجّه إنجليزي حرّ — مثل "happy rock" أو "energetic EDM with synth lead"، أو نصّ وصفيّ غنيّ للحصول على نتائج أنظف.
البنية
ثلاثة مكوّنات يجري تحميلها عند أوّل استدعاء:
| المكوّن | الدور | المصدر |
|---|---|---|
| LM المفكّك في MAGNeT | محوّل غير انحداريّ مُقنَّع فوق 4 codebooks من EnCodec. 24 طبقة (Small، 300M) أو 48 (Medium، 1.5B). إسقاطات Q/K/V/out مكمَّمة + خطّيات FFN (MLX-affine، مجموعة 64). | aufklarer/MAGNeT-{Small,Medium}-30secs-MLX-{4,8}bit |
| مرمّز النص T5-base | مرمّز بـ 110M معامل لتكييف النص. FP32 (مسار المرمّز فقط؛ لا مفكّك ولا رأس LM). | t5-base |
| مفكّك EnCodec بـ 32 kHz | مفكّك SEANet (Conv1d / ConvTranspose1d / ResnetBlock / LSTM بطبقتين) + RVQ إقليديّ بـ 4 codebooks. يحوّل الرموز المنفصلة الصادرة عن الـ LM إلى موجة بمعدّل 32 kHz. | mlx-community/encodec-32khz-float32 |
فكّ ترميز متوازٍ مُقنَّع
على عكس شقيقه الانحداريّ MusicGen، يُجري MAGNeT 50 تمريرة أماميّة إجمالًا (التقسيم الافتراضي [20, 10, 10, 10] عبر الـ 4 codebooks) مع إعادة تقنيع مجدولة بدالّة جيب التمام، وتهدئة لتوجيه دون مصنّف، ونوافذ انتباه محليّة لكلّ مرحلة. تستخدم المرحلة 0 self-attention كاملًا، بينما تستعمل المراحل 1–3 نافذة محليّة |q − k| ≤ 5 لأنّ الـ codebooks الأعلى تكتفي بصقل التفاصيل.
المتغيّرات
| المتغيّر | المعاملات | حجم الـ LM على القرص | ذروة RSS | الزمن الفعلي (سلسلة M، 30 ث) | RTF |
|---|---|---|---|---|---|
small-int4 | 300M | 287 MB | ~1.4 GB | ~10.8 ث | 0.36× |
small-int8 | 300M | 425 MB | ~1.5 GB | ~11 ث | 0.37× |
medium-int4 | 1.5B | 1.36 GB | ~2.2 GB | ~36 ث | 1.20× |
medium-int8 | 1.5B | 2.10 GB | ~3.0 GB | ~36 ث | 1.20× |
RTF أقلّ من 1.0 يعني أسرع من الزمن الحقيقي. التكميم بالكاد يغيّر الزمن الفعليّ — الانتباه هو المهيمن، لا الإسقاطات الخطّية — لذا فإنّ المكسب العمليّ من INT4 يأتي من توفير الذاكرة لا من خفض الكُمون.
بداية سريعة
import MAGNeTMusicGen
let model = try await MAGNeTMusicGen.fromPretrained(variant: .smallInt4)
let pcm = model.generate(text: "energetic upbeat rock anthem with electric guitar riffs, driving drums, bass groove")
// pcm: [Float] length 960_000 (30 s × 32 kHz mono)
try WAVWriter.write(samples: pcm, sampleRate: 32_000,
to: URL(fileURLWithPath: "out.wav"))
CLI
# Default: small-int4 (~10 s on M-series for 30 s of audio)
speech compose "happy rock" -o happy_rock.wav
# Larger model — better prompt following, ~3.5× slower
speech compose "lo-fi hip hop with mellow piano and warm vinyl crackle" \
--variant medium-int4 -o lofi.wav
# Reproducible
speech compose "energetic EDM with synth lead" --seed 42 -o edm.wav
الرايات: --variant {small,medium}-{int4,int8}، --temperature (مهدّأة، افتراضيًا 3.0)، --top-p (افتراضيًا 0.9)، --cfg-max / --cfg-min (افتراضيًا 10.0 / 1.0)، --steps "20,10,10,10" (التكرارات لكلّ codebook)، --seed.
الوسوم القصيرة مثل "happy rock" تنفع لكنّها تبدو هزيلة. الموجّهات الوصفيّة التي تذكر الآلات + الإيقاع + الحالة المزاجية تحسّن التماسك بشكل ملحوظ — في اختبار الجودة الذي أجريناه، أعطى الموجّه الأغنى معدّل عبور صفر أعلى (0.116 مقابل 0.093، أي تفاصيل ترددية أعلى) وصفر clipping. قارن:
"happy rock"— هزيل"energetic upbeat rock anthem with electric guitar riffs, driving drums, bass groove"— أغنى، وعادةً أفضل
الحزم والترخيص
تستند حزم MLX الأربع جميعها إلى facebook/magnet-small-30secs وfacebook/magnet-medium-30secs وترث ترخيص Meta: CC-BY-NC 4.0 — للاستخدام غير التجاري فقط. ويسري القيد نفسه على الصوت المُولَّد.
فصل المصادر — Open-Unmix (4 stems)
Open-Unmix HQ / UMX-L منقول إلى MLX. يقسّم مزيجاً ستيريو إلى أربعة stems — الأصوات، الإيقاع، الباس، باقي الآلات — عبر متنبّئات BiLSTM لكلّ stem ومرشّح Wiener-EM متعدّد القنوات بعد المعالجة، وكلّ ذلك يعمل من البداية إلى النهاية على MLX عبر STFT العكسيّ. RTF في الظروف الحقيقية ~0.031 (أسرع من الزمن الحقيقي بـ 32×) على سلسلة M لـ 30 ثانية من الصوت.
# Split mix.wav into vocals/drums/bass/other.wav next to it
speech separate mix.wav
# Or keep stems together
speech separate mix.wav --output stems/
import SourceSeparation
let separator = try await SourceSeparator.fromPretrained()
let stems = try separator.separate(audio: stereoSamples, sampleRate: 44_100)
// stems.vocals, stems.drums, stems.bass, stems.other — each [Float]
البنية الكاملة، والضبط، وملاحظات قياس الأداء في دليل فصل المصادر.
تحسين الكلام — DeepFilterNet3
DeepFilterNet3 على Neural Engine (CoreML). يزيل ضوضاء الخلفية من الكلام بمعدّل 48 kHz في الزمن الحقيقي بنموذج بـ 2.1M معامل — صغير بما يكفي للعمل إلى جانب خطّ ASR كخطوة معالجة مسبقة.
speech denoise noisy.wav -o clean.wav
import SpeechEnhancement
let enhancer = try await SpeechEnhancer.fromPretrained()
let clean = try enhancer.enhance(audio: noisy, sampleRate: 48_000)
الإعدادات الكاملة في دليل تحسين الكلام.
اختيار الأداة المناسبة
| تريد… | استعمل |
|---|---|
| توليد موسيقى من موجّه نصّي | MAGNeT (speech compose) |
| استخراج الأصوات أو الإيقاع من مسار موجود | Open-Unmix (speech separate) |
| تنظيف كلام صاخب قبل التفريغ | DeepFilterNet3 (speech denoise) |
| تحويل النص إلى كلام (تركيب صوتي) | VoxCPM2 أو Qwen3-TTS |