COE 592 · Assignmentواجب

Assignment 1, solvedالواجب الأول، محلولًا

Worked solutions for COE 592 Assignment 1: magnitude-based fine-grained pruning of VGG on CIFAR-10 to 20.94% of its size at 92.79% accuracy, and channel pruning that halves the MACs and keeps 92.30% after finetuning.حلول مفصّلة للواجب الأول في COE 592: تقليم دقيق الحبيبات (fine-grained pruning) قائم على المقدار (magnitude) لشبكة VGG على CIFAR-10 حتى 20.94% من حجمها بدقة 92.79%، ثم تقليم القنوات (channel pruning) الذي يخفض عدد MACs إلى النصف ويحافظ على 92.30% بعد الضبط الدقيق (finetuning).

Dueموعد التسليم
Date to be announcedيُعلن الموعد لاحقًا
Pointsالدرجات
TBCلاحقًا
Weightالوزن
TBC
Statusالحالة
Doneمنتهٍ

Notebooksدفاتر Jupyter

On this pageفي هذه الصفحة

01Overviewنظرة عامة

Assignment 1 is the MIT 6.5940 EfficientML.ai pruning lab: a VGG trained on CIFAR-10 is pruned two ways, and the notebook measures what each one buys. The answers below come from one complete run of the notebook, and every number is the one it printed.

الواجب الأول هو مختبر التقليم pruning في مقرر MIT 6.5940 EfficientML.ai: نموذج VGG مدرَّب على CIFAR-10 يُقلَّم بطريقتين، ويقيس الـ notebook ما تكسبه كل طريقة. الإجابات أدناه مأخوذة من تشغيل كامل واحد للـ notebook، وكل رقم هنا هو الرقم الذي طبعه.

MetricالمقياسDenseالنموذج الكثيفFine-grainedتقليم دقيق الحبيباتChannel prunedتقليم القنوات
Test accuracyدقة الاختبار92.95%92.95%92.79%92.79%92.30%92.30%
Accuracy before finetuningالدقة قبل إعادة التدريب الدقيقn/aلا ينطبق84.48%84.48%36.81%36.81%
Model sizeحجم النموذج35.20 MiB35.20 MiB7.37 MiB (20.94%)7.37 MiB (20.94%)about 1.8x smallerأصغر بنحو 1.8x
Parametersعدد المعاملات9.23 M9.23 Mabout 21% nonzeroنحو 21% منها غير صفري5.01 M5.01 M
MACsعدد عمليات MACs606 M606 M606 M on dense hardware606 M على عتاد كثيف305 M305 M
CPU latency, batch 1زمن الاستجابة على CPU، دفعة بحجم 13.6 ms3.6 msno real changeلا تغيير حقيقي1.8 ms1.8 ms
Before and after pruningقبل التقليم وبعده

An animated walkthrough steps through the same solution: a pruning slider on the test tensor, the sensitivity curves, the sparsity budget, the finetuning curves and the channel sorting.

يوجد شرح تفاعلي متحرك يمر بالحل نفسه خطوة بخطوة: شريط تمرير للتقليم على مصفوفة الاختبار، ومنحنيات الحساسية، وميزانية التناثر sparsity، ومنحنيات إعادة التدريب الدقيق، وترتيب القنوات.

02Part 1: fine-grained pruningالجزء 1: التقليم دقيق الحبيبات (fine-grained pruning)

Fine-grained pruning removes individual weights. It is covered in lecture 04-1 under magnitude criteria, and the per-layer ratios follow reading sensitivity curves from lecture 04-2.

التقليم دقيق الحبيبات fine-grained pruning يزيل أوزانًا منفردة. تغطيه المحاضرة 04-1 تحت معايير المقدار، وتتبع النسب الخاصة بكل طبقة درس قراءة منحنيات الحساسية من المحاضرة 04-2.

Q1: the weight distributionس1: توزيع الأوزان

Every layer has the same shape: one peak at zero, roughly symmetric, with a sharper peak and heavier tails than a Gaussian. Most weights are tiny and a few large ones sit in the tails. What changes with depth is the spread: the standard deviation falls from 0.146 in conv0 to 0.0046 in conv7.

لكل الطبقات الشكل نفسه: قمة واحدة عند الصفر، متماثل تقريبًا، بقمة أحدّ وذيول أثقل من التوزيع الطبيعي Gaussian. معظم الأوزان صغيرة جدًا، وقلة من الأوزان الكبيرة تقع في الذيول. والذي يتغير مع العمق هو الانتشار: ينخفض الانحراف المعياري من 0.146 في conv0 إلى 0.0046 في conv7.

LayerالطبقةStandard deviationالانحراف المعياريShare with |w| < 0.02نسبة الأوزان التي فيها |w| < 0.02Noteملاحظة
conv0conv00.1460.14615%15%Widest spread; only 1,728 weightsأوسع انتشار، وفيها 1,728 وزنًا فقط
conv4 to conv7من conv4 إلى conv7down to 0.0046تنخفض حتى 0.004688% to 99.7%من 88% إلى 99.7%About 90% of all weights, packed near zeroنحو 90% من كل الأوزان، متراصة قرب الصفر
classifierclassifierwide, skewedواسع وملتوٍ14%14%Range -0.23 to 0.55المدى من -0.23 إلى 0.55
Spread of the weights by layerانتشار الأوزان حسب الطبقة

Q2: magnitude-based pruningس2: التقليم القائم على المقدار (magnitude)

The importance of a weight is its absolute value. To zero a fraction ss of a tensor with nn elements, find the kk-th smallest importance with k=round⁡(s⋅n)k = \operatorname{round}(s \cdot n) and keep only what is strictly above it.

أهمية الوزن هي قيمته المطلقة. لتصفير نسبة ss من مصفوفة فيها nn عنصرًا، نجد أصغر أهمية رقم kk حيث k=round⁡(s⋅n)k = \operatorname{round}(s \cdot n)، ونُبقي فقط ما هو أكبر منها تمامًا.

num_zeros = round(num_elements * sparsity)
importance = torch.abs(tensor)
threshold = importance.view(-1).kthvalue(num_zeros).values
mask = torch.gt(importance, threshold)
tensor.mul_(mask)
Q2: the four blanks of fine_grained_prune, then the mask is applied
  • kthvalue works on a 1-D tensor, which is why the importance is flattened with view(-1) first.تعمل kthvalue على مصفوفة أحادية البعد، ولهذا تُسطَّح الأهمية أولًا باستخدام view(-1).
  • The mask uses a strict >, so the kk-th weight itself is pruned and exactly kk weights become zero when there are no ties.يستخدم القناع مقارنة صارمة >، لذلك يُقلَّم الوزن رقم kk نفسه، ويصبح بالضبط kk وزنًا صفرًا عندما لا توجد قيم متساوية.
  • On the 5 x 5 test tensor at target sparsity 0.75, 19 of 25 weights are zeroed. The test prints a sparsity of 0.76 because 19/25 = 0.76, and passes.على مصفوفة الاختبار 5 x 5 وبتناثر مستهدف 0.75، يُصفَّر 19 وزنًا من أصل 25. يطبع الاختبار تناثرًا قدره 0.76 لأن 19/25 = 0.76، وينجح.

Q3: hitting 10 nonzerosس3: الوصول إلى 10 قيم غير صفرية

Worked exampleمثال محلول

Keep exactly 10 nonzeros in the 5 x 5 test tensorأبقِ 10 قيم غير صفرية بالضبط في مصفوفة الاختبار 5 x 5

  1. Count what must goعُدّ ما يجب حذفه

    The tensor has 25 elements and the target is 10 survivors, so 15 must be zero.

    في المصفوفة 25 عنصرًا والهدف 10 قيم باقية، لذلك يجب أن يصبح 15 عنصرًا صفرًا.

  2. Turn it into a sparsityحوّله إلى نسبة تناثر

    s=1525=0.6s = \frac{15}{25} = 0.6
    s=1525=0.6s = \frac{15}{25} = 0.6
  3. Resultالنتيجة

    target_sparsity = 0.6. The pruned tensor has sparsity 0.60 and the test passes.

    target_sparsity = 0.6. تناثر المصفوفة بعد التقليم 0.60 وينجح الاختبار.

Q4: the sensitivity scanس4: مسح الحساسية (sensitivity scan)

The scan prunes one layer at a time at sparsities 0.4 to 0.9, keeps every other layer dense, and measures test accuracy. The dense model scores 92.95%. Values under the plotted lower bound of 89.42% are in bold.

يقلّم المسح طبقة واحدة في كل مرة بنسب تناثر من 0.4 إلى 0.9، ويُبقي باقي الطبقات كثيفة، ويقيس دقة الاختبار. النموذج الكثيف يحقق 92.95%. القيم الأقل من الحد الأدنى المرسوم 89.42% مكتوبة بخط عريض.

Layerالطبقة0.40.40.50.50.60.60.70.70.80.80.90.9
conv092.4291.1987.5583.3969.4131.81
conv192.9392.8892.7192.4091.3284.78
conv292.9492.6492.4691.7789.8578.56
conv392.8692.7292.2391.0985.3551.31
conv492.8892.6892.2289.4776.8738.78
conv592.9292.7192.6391.8889.9082.19
conv692.9492.8692.6592.1090.5883.65
conv792.9492.9292.8892.8192.6391.34
classifier92.9192.8392.8192.9792.6892.52
Test accuracy (%) with one layer pruned, values under the bound in boldدقة الاختبار (%) مع تقليم طبقة واحدة، والقيم الأقل من الحد بخط عريض

The three written answersالإجابات المكتوبة الثلاث

Q4.1 trendQ4.1 الاتجاه العام
Accuracy falls as sparsity rises, and not linearly. Up to about 0.6 most layers lose only a few tenths of a point because only near-zero weights go. Past 0.7 the drop speeds up, because pruning starts to remove large, important weights.تنخفض الدقة كلما زاد التناثر، وليس انخفاضًا خطيًا. حتى نحو 0.6 تخسر معظم الطبقات أعشارًا قليلة من النقطة فقط، لأن الأوزان القريبة من الصفر وحدها هي التي تُحذف. وبعد 0.7 يتسارع الانخفاض، لأن التقليم يبدأ بإزالة أوزان كبيرة ومهمة.
Q4.2 same for all?Q4.2 هل هو نفسه للجميع؟
No. conv7 and the classifier stay above the bound even at 0.9. conv1, conv2, conv5 and conv6 hold up to 0.8. conv3 and conv4 fall below it at 0.8. conv0 is already below it at 0.6.لا. تبقى conv7 والمصنِّف classifier فوق الحد حتى عند 0.9. وتصمد conv1 وconv2 وconv5 وconv6 حتى 0.8. وتنزل conv3 وconv4 تحته عند 0.8. أما conv0 فهي تحته أصلًا عند 0.6.
Q4.3 most sensitiveQ4.3 الطبقة الأكثر حساسية
backbone.conv0. It is the only layer that loses more than a tenth of a point at 0.4 and it collapses to 31.81% at 0.9. With 1,728 weights reading the raw RGB input, it has almost no redundancy.backbone.conv0. هي الطبقة الوحيدة التي تخسر أكثر من عُشر نقطة عند 0.4، وتنهار إلى 31.81% عند 0.9. وبما أن فيها 1,728 وزنًا فقط تقرأ مدخل RGB الخام، فلا يكاد يوجد فيها أي فائض redundancy.

Q5: per-layer sparsity and finetuningس5: التناثر (sparsity) لكل طبقة والضبط الدقيق (finetuning)

The goal is at most 25% of the dense size and more than 92.5% accuracy after five epochs of finetuning. Two facts set the ratios: the scan says how much each layer tolerates, and the parameter count says where the size is. conv4 to conv7 hold about 90% of the weights and tolerate pruning well, so they take the high ratios. conv0 is fragile but tiny, so pruning it lightly costs almost nothing in size.

الهدف حجم لا يتجاوز 25% من حجم النموذج الكثيف، ودقة أعلى من 92.5% بعد خمس حقب من إعادة التدريب الدقيق. حقيقتان تحددان النسب: المسح يبيّن كم تتحمل كل طبقة، وعدد المعاملات يبيّن أين يتركز الحجم. الطبقات من conv4 إلى conv7 تحمل نحو 90% من الأوزان وتتحمل التقليم جيدًا، لذلك تأخذ النسب العالية. أما conv0 فهشة لكنها صغيرة جدًا، فتقليمها بخفة لا يكلف شيئًا يُذكر من الحجم.

sparsity_dict = {
    'backbone.conv0.weight': 0.4,
    'backbone.conv1.weight': 0.5,
    'backbone.conv2.weight': 0.6,
    'backbone.conv3.weight': 0.6,
    'backbone.conv4.weight': 0.7,
    'backbone.conv5.weight': 0.8,
    'backbone.conv6.weight': 0.85,
    'backbone.conv7.weight': 0.85,
    'classifier.weight': 0.7,
}
Q5: per-layer sparsity
StageالمرحلةTest accuracyدقة الاختبار
Before finetuningقبل إعادة التدريب الدقيق84.48%84.48%
Epoch 1الحقبة 192.52%92.52%
Epoch 2الحقبة 292.78%92.78%
Epoch 3الحقبة 392.74%92.74%
Epoch 4الحقبة 492.73%92.73%
Epoch 5الحقبة 592.79%92.79%
Masked finetuning of the fine-grained modelإعادة التدريب الدقيق مع الأقنعة للنموذج دقيق الحبيبات

03Part 2: channel pruningالجزء 2: تقليم القنوات (channel pruning)

Channel pruning removes whole output channels, so the result is a smaller dense network. Lecture 04-1 places it at the regular end of the granularity spectrum.

تقليم القنوات channel pruning يزيل قنوات مخرجات كاملة، فتكون النتيجة شبكة كثيفة أصغر. وتضعه المحاضرة 04-1 في الطرف المنتظم من طيف مستوى الحبيبات.

Q6: removing channelsس6: حذف القنوات

With a ratio of 0.3, each of the seven boundaries between the eight convs keeps round⁡(0.7⋅C)\operatorname{round}(0.7 \cdot C) channels. The loop already trims the output side of the previous conv and its BatchNorm. The missing line trims the matching input side of the next conv, which is dimension 1 of its weight.

بنسبة تقليم 0.3، تُبقي كل حدّ من الحدود السبعة بين طبقات الالتفاف conv الثماني round⁡(0.7⋅C)\operatorname{round}(0.7 \cdot C) قناة. الحلقة تقص أصلًا جانب المخرجات في طبقة conv السابقة وفي BatchNorm التابعة لها. والسطر الناقص يقص جانب المدخلات المقابل في طبقة conv التالية، وهو البعد 1 من مصفوفة أوزانها.

def get_num_channels_to_keep(channels: int, prune_ratio: float) -> int:
    return int(round(channels * (1. - prune_ratio)))

next_conv.weight.set_(next_conv.weight.detach()[:, :n_keep])
Q6: channels to keep, and the next conv's inputs

The pruned model has 305,388,064 MACs, exactly the value the notebook checks for.

النموذج المقلَّم فيه 305,388,064 عملية MAC، وهي بالضبط القيمة التي يتحقق منها الـ notebook.

Q7: keeping the important channelsس7: الإبقاء على القنوات المهمة

Keeping the first kk channels is arbitrary. Sorting ranks each channel by the Frobenius norm of the next conv's weights that read it, then reorders the previous conv's outputs, its BatchNorm, and the next conv's inputs with the same permutation. The function the network computes does not change, so the sorted dense model still scores 92.95%. The check passes.

إبقاء أول kk قناة اختيار اعتباطي. أما الترتيب فيرتّب كل قناة حسب معيار فروبينيوس Frobenius norm لأوزان طبقة conv التالية التي تقرأ هذه القناة، ثم يعيد ترتيب مخرجات طبقة conv السابقة وBatchNorm التابعة لها ومدخلات طبقة conv التالية بالتبديل نفسه. الدالة التي تحسبها الشبكة لا تتغير، لذلك يبقى النموذج الكثيف بعد الترتيب على دقة 92.95%، وينجح التحقق.

importance = torch.norm(channel_weight)

next_conv.weight.copy_(torch.index_select(next_conv.weight.detach(), 1, sort_idx))
Q7: channel importance, and the next conv's input reorder
StageالمرحلةTest accuracyدقة الاختبار
Pruned, first channels keptبعد التقليم مع إبقاء القنوات الأولى28.14%28.14%
Pruned after sorting by normبعد التقليم مع الترتيب حسب المعيار36.81%36.81%
Epoch 1 of finetuningالحقبة 1 من إعادة التدريب الدقيق91.61%91.61%
Epoch 3الحقبة 392.07%92.07%
Epoch 5الحقبة 592.30%92.30%
Accuracy of the channel-pruned modelدقة النموذج المقلَّم قنواتيًا

Sorting lifts the accuracy right after pruning from 28.14% to 36.81%, and five epochs of finetuning bring it to 92.30%. This matches the lecture's point on fine-tuning after pruning: coarse pruning costs a lot at first and needs retraining to recover.

يرفع الترتيب الدقة مباشرة بعد التقليم من 28.14% إلى 36.81%، وتوصلها خمس حقب من إعادة التدريب الدقيق إلى 92.30%. وهذا يوافق ما تقوله المحاضرة عن إعادة التدريب الدقيق بعد التقليم: التقليم الخشن مكلف كثيرًا في البداية ويحتاج إلى إعادة تدريب كي يتعافى.

Q8: MACs against latencyس8: عدد MACs مقابل زمن الاستجابة (latency)

A convolution costs Cin⋅Cout⋅K2⋅Hout⋅WoutC_{in} \cdot C_{out} \cdot K^2 \cdot H_{out} \cdot W_{out} MACs. Pruning30% of the channels shrinks both CinC_{in} and CoutC_{out} of every inner conv to 0.7x, so its cost scales by 0.72=0.490.7^2 = 0.49, about half.

تكلفة طبقة الالتفاف هي Cin⋅Cout⋅K2⋅Hout⋅WoutC_{in} \cdot C_{out} \cdot K^2 \cdot H_{out} \cdot W_{out} عملية MAC. تقليم 30% من القنوات يقلّص كلًا من CinC_{in} وCoutC_{out} في كل طبقة conv داخلية إلى 0.7x، فتتغير تكلفتها بمعامل 0.72=0.490.7^2 = 0.49، أي النصف تقريبًا.

MetricالمقياسOriginalالأصليPrunedالمقلَّمReductionنسبة التخفيض
Latency (ms), CPU, batch 1زمن الاستجابة (ms) على CPU، دفعة بحجم 13.63.61.81.82.0x2.0x
MACs (M)عمليات MACs (M)6066063053052.0x2.0x
Parameters (M)المعاملات (M)9.239.235.015.011.8x1.8x
Measured by the notebookكما قاسها الـ notebook

04Q9: which pruning for a phoneس9: أي تقليم يناسب الهاتف

AspectالجانبFine-grainedدقيق الحبيباتChannelالقنوات
Granularityمستوى الدقة في التقليمSingle weights, the most flexibleأوزان منفردة، وهو الأكثر مرونةWhole channels, the most regularقنوات كاملة، وهو الأكثر انتظامًا
Compression hereالضغط المحقق هنا20.94% of the size at 92.79%20.94% من الحجم مع دقة 92.79%2.0x fewer MACs at 92.30%عمليات MACs أقل بمقدار 2.0x مع دقة 92.30%
Real speedupالتسريع الفعليOnly with sparse formats, sparse kernels or accelerators such as EIEفقط مع صيغ التخزين المتناثر أو أنوية حساب متناثرة أو مسرّعات مثل EIEOn any hardware, the model is simply smaller and denseعلى أي عتاد، فالنموذج ببساطة أصغر وكثيف
CostالتكلفةIrregular pattern; index overhead eats into the savingنمط غير منتظم، وعبء الفهارس يأكل جزءًا من التوفيرLarge drop right after pruning, needs finetuning and a good channel rankingانخفاض كبير مباشرة بعد التقليم، ويحتاج إلى إعادة تدريب دقيق وترتيب جيد للقنوات
Q9.1: fine-grained against channel pruningالسؤال Q9.1: التقليم دقيق الحبيبات مقابل تقليم القنوات

For Q9.2, a smartphone should use channel pruning. Phone CPUs, GPUs and NPUs, and the runtimes on them, are built for dense tensor math and mostly cannot skip scattered zeros. A channel-pruned model is just a smaller dense model, so its MAC and parameter savings turn directly into lower latency, memory and energy. Here that meant 2.0x fewer MACs and a 1.6x to 2.0x CPU speedup, depending on the run.

في السؤال Q9.2، يجب أن يستخدم الهاتف الذكي تقليم القنوات. فمعالجات CPU وGPU وNPU في الهواتف، وبيئات التشغيل عليها، مصممة لحساب المصفوفات الكثيفة dense، وفي الغالب لا تستطيع تخطي الأصفار المبعثرة. النموذج المقلَّم قنواتيًا هو ببساطة نموذج كثيف أصغر، لذلك يتحول توفيره في عمليات MACs وفي المعاملات مباشرة إلى زمن استجابة وذاكرة وطاقة أقل. وهنا كان ذلك يعني عمليات MACs أقل بمقدار 2.0x وتسريعًا على CPU بين 1.6x و2.0x بحسب التشغيل.

05Running the notebookتشغيل دفتر Jupyter

The notebook was written for Colab and asserts that CUDA exists. It runs locally once the device is chosen instead of assumed.

كُتب الـ notebook لبيئة Colab ويتحقق بأمر assert من وجود CUDA. ويعمل محليًا بمجرد أن يُختار الجهاز بدلًا من افتراضه.

device = torch.device(
    "cuda" if torch.cuda.is_available()
    else "mps" if torch.backends.mps.is_available()
    else "cpu"
)
Replaces the CUDA assert; every .cuda() becomes .to(device)
uv init --bare --python 3.14
uv add torch torchvision torchprofile numpy matplotlib tqdm ipykernel ipywidgets nbconvert
uv run jupyter nbconvert --to notebook --execute --inplace \
  --ExecutePreprocessor.timeout=-1 coe-592-assignment-1.ipynb
Environment and a headless run of the whole notebook
  • On an Apple M4 with the MPS backend the full run takes about 15 minutes. The sensitivity scan and the two five-epoch finetunes take most of that.على Apple M4 مع واجهة MPS يستغرق التشغيل الكامل نحو 15 دقيقة، ويأخذ معظم هذا الوقت مسح الحساسية وجولتا إعادة التدريب الدقيق ذواتا الحقب الخمس.
  • Latency is still measured on the CPU, as the lab intends, so the models are moved back to the device after profiling.ما زال زمن الاستجابة يُقاس على CPU كما يقصد المختبر، لذلك تُعاد النماذج إلى الجهاز بعد قياس الأداء profiling.
  • Set pin_memory only when CUDA is available. MPS does not support it and warns on every batch.فعّل pin_memory فقط عندما يتوفر CUDA، لأن MPS لا يدعمه ويطبع تحذيرًا مع كل دفعة.

06Sourcesالمصادر

The papers and course material behind the methods used above.

الأوراق البحثية ومواد المقرر التي تقوم عليها الطرق المستخدمة أعلاه.

Sourcesالمصادر