UNPKG

aws-cdk-neuronx-patterns

Version:
186 lines 16.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const aws_cdk_lib_1 = require("aws-cdk-lib"); const calculator_1 = require("./calculator"); const model_1 = require("./model"); const neuronx_instance_type_1 = require("./neuronx-instance-type"); describe("When the attention head is divisible", () => { test("Inf2", () => { const tensorParallel = (0, calculator_1.calcTensorParallel)(neuronx_instance_type_1.NeuronxInstanceType.INF2_48XLARGE, aws_cdk_lib_1.Size.gibibytes(16), 32); expect(tensorParallel).toEqual([ { tp: 1, workers: 24, usage: 1, }, { tp: 2, workers: 12, usage: 1, }, { tp: 4, workers: 6, usage: 1, }, { tp: 8, workers: 3, usage: 1, }, ]); }); test("Trn1", () => { const tensorParallel = (0, calculator_1.calcTensorParallel)(neuronx_instance_type_1.NeuronxInstanceType.TRN1_32XLARGE, aws_cdk_lib_1.Size.gibibytes(16), 48); expect(tensorParallel).toEqual([ { tp: 1, workers: 32, usage: 1, }, { tp: 2, workers: 16, usage: 1, }, { tp: 8, workers: 4, usage: 1, }, { tp: 16, workers: 2, usage: 1, }, ]); }); test("Trn2", () => { const tensorParallel = (0, calculator_1.calcTensorParallel)(neuronx_instance_type_1.NeuronxInstanceType.TRN2_48XLARGE, aws_cdk_lib_1.Size.gibibytes(24), 64); expect(tensorParallel).toEqual([ { tp: 1, workers: 64, usage: 1, }, { tp: 2, workers: 32, usage: 1, }, { tp: 4, workers: 16, usage: 1, }, { tp: 8, workers: 8, usage: 1, }, { tp: 16, workers: 4, usage: 1, }, { tp: 32, workers: 2, usage: 1, }, { tp: 64, workers: 1, usage: 1, }, ]); }); }); describe("The one with low usage is shown last", () => { test("Inf2", () => { const tensorParallel = (0, calculator_1.calcTensorParallel)(neuronx_instance_type_1.NeuronxInstanceType.INF2_24XLARGE, aws_cdk_lib_1.Size.gibibytes(16), 32); expect(tensorParallel).toEqual([ { tp: 1, workers: 12, usage: 1, }, { tp: 2, workers: 6, usage: 1, }, { tp: 4, workers: 3, usage: 1, }, { tp: 8, workers: 1, usage: 0.6666666666666666, }, ]); }); test("Trn1", () => { const tensorParallel = (0, calculator_1.calcTensorParallel)(neuronx_instance_type_1.NeuronxInstanceType.TRN1_32XLARGE, aws_cdk_lib_1.Size.gibibytes(16), 32); expect(tensorParallel).toEqual([ { tp: 1, workers: 32, usage: 1, }, { tp: 2, workers: 16, usage: 1, }, { tp: 8, workers: 4, usage: 1, }, { tp: 16, workers: 2, usage: 1, }, { tp: 32, workers: 1, usage: 1, }, ]); }); test("Trn2", () => { const tensorParallel = (0, calculator_1.calcTensorParallel)(neuronx_instance_type_1.NeuronxInstanceType.TRN2_3XLARGE, aws_cdk_lib_1.Size.gibibytes(24), 32); expect(tensorParallel).toEqual([ { tp: 1, workers: 4, usage: 1, }, { tp: 2, workers: 2, usage: 1, }, { tp: 4, workers: 1, usage: 1, }, ]); }); }); describe("When the memory footprint is calculated", () => { test("Million size models are calculatable", () => { const memoryFootprint = (0, calculator_1.calcMemoryFootprint)(576, 30, model_1.DataTypeBits.BF16_OR_FP16, 128, 1); expect(memoryFootprint.toGibibytes()).toEqual(1); }); test("Billion size models are calculatable", () => { const memoryFootprint = (0, calculator_1.calcMemoryFootprint)(6144, 48, model_1.DataTypeBits.BF16_OR_FP16, 1024, 1); expect(memoryFootprint.toGibibytes()).toEqual(42); }); }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsY3VsYXRvci50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2Jhc2UvbmV1cm9ueC9jYWxjdWxhdG9yLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw2Q0FBbUM7QUFDbkMsNkNBQXVFO0FBQ3ZFLG1DQUF1QztBQUN2QyxtRUFBOEQ7QUFFOUQsUUFBUSxDQUFDLHNDQUFzQyxFQUFFLEdBQUcsRUFBRTtJQUNwRCxJQUFJLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRTtRQUNoQixNQUFNLGNBQWMsR0FBRyxJQUFBLCtCQUFrQixFQUN2QywyQ0FBbUIsQ0FBQyxhQUFhLEVBQ2pDLGtCQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxFQUNsQixFQUFFLENBQ0gsQ0FBQztRQUNGLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxPQUFPLENBQUM7WUFDN0I7Z0JBQ0UsRUFBRSxFQUFFLENBQUM7Z0JBQ0wsT0FBTyxFQUFFLEVBQUU7Z0JBQ1gsS0FBSyxFQUFFLENBQUM7YUFDVDtZQUNEO2dCQUNFLEVBQUUsRUFBRSxDQUFDO2dCQUNMLE9BQU8sRUFBRSxFQUFFO2dCQUNYLEtBQUssRUFBRSxDQUFDO2FBQ1Q7WUFDRDtnQkFDRSxFQUFFLEVBQUUsQ0FBQztnQkFDTCxPQUFPLEVBQUUsQ0FBQztnQkFDVixLQUFLLEVBQUUsQ0FBQzthQUNUO1lBQ0Q7Z0JBQ0UsRUFBRSxFQUFFLENBQUM7Z0JBQ0wsT0FBTyxFQUFFLENBQUM7Z0JBQ1YsS0FBSyxFQUFFLENBQUM7YUFDVDtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0gsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUU7UUFDaEIsTUFBTSxjQUFjLEdBQUcsSUFBQSwrQkFBa0IsRUFDdkMsMkNBQW1CLENBQUMsYUFBYSxFQUNqQyxrQkFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsRUFDbEIsRUFBRSxDQUNILENBQUM7UUFD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QUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUM7QUFFSCxRQUFRLENBQUMseUNBQXlDLEVBQUUsR0FBRyxFQUFFO0lBQ3ZELElBQUksQ0FBQyxzQ0FBc0MsRUFBRSxHQUFHLEVBQUU7UUFDaEQsTUFBTSxlQUFlLEdBQUcsSUFBQSxnQ0FBbUIsRUFDekMsR0FBRyxFQUNILEVBQUUsRUFDRixvQkFBWSxDQUFDLFlBQVksRUFDekIsR0FBRyxFQUNILENBQUMsQ0FDRixDQUFDO1FBQ0YsTUFBTSxDQUFDLGVBQWUsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNuRCxDQUFDLENBQUMsQ0FBQztJQUNILElBQUksQ0FBQyxzQ0FBc0MsRUFBRSxHQUFHLEVBQUU7UUFDaEQsTUFBTSxlQUFlLEdBQUcsSUFBQSxnQ0FBbUIsRUFDekMsSUFBSSxFQUNKLEVBQUUsRUFDRixvQkFBWSxDQUFDLFlBQVksRUFDekIsSUFBSSxFQUNKLENBQUMsQ0FDRixDQUFDO1FBQ0YsTUFBTSxDQUFDLGVBQWUsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNwRCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU2l6ZSB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHsgY2FsY01lbW9yeUZvb3RwcmludCwgY2FsY1RlbnNvclBhcmFsbGVsIH0gZnJvbSBcIi4vY2FsY3VsYXRvclwiO1xuaW1wb3J0IHsgRGF0YVR5cGVCaXRzIH0gZnJvbSBcIi4vbW9kZWxcIjtcbmltcG9ydCB7IE5ldXJvbnhJbnN0YW5jZVR5cGUgfSBmcm9tIFwiLi9uZXVyb254LWluc3RhbmNlLXR5cGVcIjtcblxuZGVzY3JpYmUoXCJXaGVuIHRoZSBhdHRlbnRpb24gaGVhZCBpcyBkaXZpc2libGVcIiwgKCkgPT4ge1xuICB0ZXN0KFwiSW5mMlwiLCAoKSA9PiB7XG4gICAgY29uc3QgdGVuc29yUGFyYWxsZWwgPSBjYWxjVGVuc29yUGFyYWxsZWwoXG4gICAgICBOZXVyb254SW5zdGFuY2VUeXBlLklORjJfNDhYTEFSR0UsXG4gICAgICBTaXplLmdpYmlieXRlcygxNiksXG4gICAgICAzMixcbiAgICApO1xuICAgIGV4cGVjdCh0ZW5zb3JQYXJhbGxlbCkudG9FcXVhbChbXG4gICAgICB7XG4gICAgICAgIHRwOiAxLFxuICAgICAgICB3b3JrZXJzOiAyNCxcbiAgICAgICAgdXNhZ2U6IDEsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB0cDogMixcbiAgICAgICAgd29ya2VyczogMTIsXG4gICAgICAgIHVzYWdlOiAxLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgdHA6IDQsXG4gICAgICAgIHdvcmtlcnM6IDYsXG4gICAgICAgIHVzYWdlOiAxLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgdHA6IDgsXG4gICAgICAgIHdvcmtlcnM6IDMsXG4gICAgICAgIHVzYWdlOiAxLFxuICAgICAgfSxcbiAgICBdKTtcbiAgfSk7XG4gIHRlc3QoXCJUcm4xXCIsICgpID0+IHtcbiAgICBjb25zdCB0ZW5zb3JQYXJhbGxlbCA9IGNhbGNUZW5zb3JQYXJhbGxlbChcbiAgICAgIE5ldXJvbnhJbnN0YW5jZVR5cGUuVFJOMV8zMlhMQVJHRSxcbiAgICAgIFNpemUuZ2liaWJ5dGVzKDE2KSxcbiAgICAgIDQ4LFxuICAgICk7XG4gICAgZXhwZWN0KHRlbnNvclBhcmFsbGVsKS50b0VxdWFsKFtcbiAgICAgIHtcbiAgICAgICAgdHA6IDEsXG4gICAgICAgIHdvcmtlcnM6IDMyLFxuICAgICAgICB1c2FnZTogMSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHRwOiAyLFxuICAgICAgICB3b3JrZXJzOiAxNixcbiAgICAgICAgdXNhZ2U6IDEsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB0cDogOCxcbiAgICAgICAgd29ya2VyczogNCxcbiAgICAgICAgdXNhZ2U6IDEsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB0cDogMTYsXG4gICAgICAgIHdvcmtlcnM6IDIsXG4gICAgICAgIHVzYWdlOiAxLFxuICAgICAgfSxcbiAgICBdKTtcbiAgfSk7XG4gIHRlc3QoXCJUcm4yXCIsICgpID0+IHtcbiAgICBjb25zdCB0ZW5zb3JQYXJhbGxlbCA9IGNhbGNUZW5zb3JQYXJhbGxlbChcbiAgICAgIE5ldXJvbnhJbnN0YW5jZVR5cGUuVFJOMl80OFhMQVJHRSxcbiAgICAgIFNpemUuZ2liaWJ5dGVzKDI0KSxcbiAgICAgIDY0LFxuICAgICk7XG4gICAgZXhwZWN0KHRlbnNvclBhcmFsbGVsKS50b0VxdWFsKFtcbiAgICAgIHtcbiAgICAgICAgdHA6IDEsXG4gICAgICAgIHdvcmtlcnM6IDY0LFxuICAgICAgICB1c2FnZTogMSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHRwOiAyLFxuICAgICAgICB3b3JrZXJzOiAzMixcbiAgICAgICAgdXNhZ2U6IDEsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB0cDogNCxcbiAgICAgICAgd29ya2VyczogMTYsXG4gICAgICAgIHVzYWdlOiAxLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgdHA6IDgsXG4gICAgICAgIHdvcmtlcnM6IDgsXG4gICAgICAgIHVzYWdlOiAxLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgdHA6IDE2LFxuICAgICAgICB3b3JrZXJzOiA0LFxuICAgICAgICB1c2FnZTogMSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHRwOiAzMixcbiAgICAgICAgd29ya2VyczogMixcbiAgICAgICAgdXNhZ2U6IDEsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB0cDogNjQsXG4gICAgICAgIHdvcmtlcnM6IDEsXG4gICAgICAgIHVzYWdlOiAxLFxuICAgICAgfSxcbiAgICBdKTtcbiAgfSk7XG59KTtcbmRlc2NyaWJlKFwiVGhlIG9uZSB3aXRoIGxvdyB1c2FnZSBpcyBzaG93biBsYXN0XCIsICgpID0+IHtcbiAgdGVzdChcIkluZjJcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHRlbnNvclBhcmFsbGVsID0gY2FsY1RlbnNvclBhcmFsbGVsKFxuICAgICAgTmV1cm9ueEluc3RhbmNlVHlwZS5JTkYyXzI0WExBUkdFLFxuICAgICAgU2l6ZS5naWJpYnl0ZXMoMTYpLFxuICAgICAgMzIsXG4gICAgKTtcbiAgICBleHBlY3QodGVuc29yUGFyYWxsZWwpLnRvRXF1YWwoW1xuICAgICAge1xuICAgICAgICB0cDogMSxcbiAgICAgICAgd29ya2VyczogMTIsXG4gICAgICAgIHVzYWdlOiAxLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgdHA6IDIsXG4gICAgICAgIHdvcmtlcnM6IDYsXG4gICAgICAgIHVzYWdlOiAxLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgdHA6IDQsXG4gICAgICAgIHdvcmtlcnM6IDMsXG4gICAgICAgIHVzYWdlOiAxLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgdHA6IDgsXG4gICAgICAgIHdvcmtlcnM6IDEsXG4gICAgICAgIHVzYWdlOiAwLjY2NjY2NjY2NjY2NjY2NjYsXG4gICAgICB9LFxuICAgIF0pO1xuICB9KTtcbiAgdGVzdChcIlRybjFcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHRlbnNvclBhcmFsbGVsID0gY2FsY1RlbnNvclBhcmFsbGVsKFxuICAgICAgTmV1cm9ueEluc3RhbmNlVHlwZS5UUk4xXzMyWExBUkdFLFxuICAgICAgU2l6ZS5naWJpYnl0ZXMoMTYpLFxuICAgICAgMzIsXG4gICAgKTtcbiAgICBleHBlY3QodGVuc29yUGFyYWxsZWwpLnRvRXF1YWwoW1xuICAgICAge1xuICAgICAgICB0cDogMSxcbiAgICAgICAgd29ya2VyczogMzIsXG4gICAgICAgIHVzYWdlOiAxLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgdHA6IDIsXG4gICAgICAgIHdvcmtlcnM6IDE2LFxuICAgICAgICB1c2FnZTogMSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHRwOiA4LFxuICAgICAgICB3b3JrZXJzOiA0LFxuICAgICAgICB1c2FnZTogMSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHRwOiAxNixcbiAgICAgICAgd29ya2VyczogMixcbiAgICAgICAgdXNhZ2U6IDEsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB0cDogMzIsXG4gICAgICAgIHdvcmtlcnM6IDEsXG4gICAgICAgIHVzYWdlOiAxLFxuICAgICAgfSxcbiAgICBdKTtcbiAgfSk7XG4gIHRlc3QoXCJUcm4yXCIsICgpID0+IHtcbiAgICBjb25zdCB0ZW5zb3JQYXJhbGxlbCA9IGNhbGNUZW5zb3JQYXJhbGxlbChcbiAgICAgIE5ldXJvbnhJbnN0YW5jZVR5cGUuVFJOMl8zWExBUkdFLFxuICAgICAgU2l6ZS5naWJpYnl0ZXMoMjQpLFxuICAgICAgMzIsXG4gICAgKTtcbiAgICBleHBlY3QodGVuc29yUGFyYWxsZWwpLnRvRXF1YWwoW1xuICAgICAge1xuICAgICAgICB0cDogMSxcbiAgICAgICAgd29ya2VyczogNCxcbiAgICAgICAgdXNhZ2U6IDEsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB0cDogMixcbiAgICAgICAgd29ya2VyczogMixcbiAgICAgICAgdXNhZ2U6IDEsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB0cDogNCxcbiAgICAgICAgd29ya2VyczogMSxcbiAgICAgICAgdXNhZ2U6IDEsXG4gICAgICB9LFxuICAgIF0pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZShcIldoZW4gdGhlIG1lbW9yeSBmb290cHJpbnQgaXMgY2FsY3VsYXRlZFwiLCAoKSA9PiB7XG4gIHRlc3QoXCJNaWxsaW9uIHNpemUgbW9kZWxzIGFyZSBjYWxjdWxhdGFibGVcIiwgKCkgPT4ge1xuICAgIGNvbnN0IG1lbW9yeUZvb3RwcmludCA9IGNhbGNNZW1vcnlGb290cHJpbnQoXG4gICAgICA1NzYsXG4gICAgICAzMCxcbiAgICAgIERhdGFUeXBlQml0cy5CRjE2X09SX0ZQMTYsXG4gICAgICAxMjgsXG4gICAgICAxLFxuICAgICk7XG4gICAgZXhwZWN0KG1lbW9yeUZvb3RwcmludC50b0dpYmlieXRlcygpKS50b0VxdWFsKDEpO1xuICB9KTtcbiAgdGVzdChcIkJpbGxpb24gc2l6ZSBtb2RlbHMgYXJlIGNhbGN1bGF0YWJsZVwiLCAoKSA9PiB7XG4gICAgY29uc3QgbWVtb3J5Rm9vdHByaW50ID0gY2FsY01lbW9yeUZvb3RwcmludChcbiAgICAgIDYxNDQsXG4gICAgICA0OCxcbiAgICAgIERhdGFUeXBlQml0cy5CRjE2X09SX0ZQMTYsXG4gICAgICAxMDI0LFxuICAgICAgMSxcbiAgICApO1xuICAgIGV4cGVjdChtZW1vcnlGb290cHJpbnQudG9HaWJpYnl0ZXMoKSkudG9FcXVhbCg0Mik7XG4gIH0pO1xufSk7XG4iXX0=