{ "cells": [ { "cell_type": "markdown", "id": "substantial-impact", "metadata": {}, "source": [ "# Welcome to Manim!" ] }, { "cell_type": "markdown", "id": "first-armenia", "metadata": {}, "source": [ "This is a temporary test environment in which you can play around with Manim without the need of installing it locally. Some basic knowledge of Python is helpful! Keep in mind that this is a *temporary* environment, though: your changes will not be saved and cannot be shared with others. To save your work, you will need to download the notebook file (\"File > Download as > Notebook (.ipynb)\"). Enjoy!\n", "\n", "> *Useful resources:* [Documentation](https://docs.manim.community), [Discord](https://discord.gg/mMRrZQW), [Reddit](https://www.reddit.com/r/manim/)" ] }, { "cell_type": "markdown", "id": "honest-cruise", "metadata": {}, "source": [ "## Setup" ] }, { "cell_type": "code", "execution_count": null, "id": "f8ffa0be-d1ae-4b1d-8827-01e11ef5be68", "metadata": { "tags": [] }, "outputs": [], "source": [ "!wget -O user.svg https://pic.onlinewebfonts.com/thumbnails/icons_308642.svg" ] }, { "cell_type": "markdown", "id": "governing-increase", "metadata": {}, "source": [ "We begin our short walkthrough by importing everything from the library. Run the following code cell to do so (focus the cell and hit the *Run* button above, or press `Shift`+`Enter` – you can find more information about how to navigate and work with Jupyter notebooks in the *Help* menu at the top of this page).\n", "\n", "The second line controls the maximum width used to display videos in this notebook, and the third line controls the verbosity of the log output. Feel free to adapt both of these settings to your liking." ] }, { "cell_type": "code", "execution_count": null, "id": "eaab1b64-4833-4e7d-97e7-3c5324c742df", "metadata": { "tags": [] }, "outputs": [], "source": [ "from manim import *\n", "\n", "config.media_width = \"75%\"\n", "config.verbosity = \"WARNING\"" ] }, { "cell_type": "code", "execution_count": null, "id": "257cf337-948e-4ef7-aae3-2fb7b5b58602", "metadata": { "tags": [] }, "outputs": [], "source": [ "%%manim -qm --format=gif LatencyVisualization\n", "\n", "from manim import *\n", "\n", "text = \"The cake is a lie\"\n", "text_list = text.split(\" \")\n", "rounds = 3\n", "class LatencyVisualization(Scene):\n", "\n", " def construct(self):\n", " # Setup LLM and user\n", " llm_box = Rectangle(width=2, height=1).set_fill(BLUE, opacity=0.5).set_stroke(BLUE, width=2).to_edge(LEFT)\n", " llm_text = Text(\"LLM\", color=WHITE).move_to(llm_box.get_center())\n", " user_svg = SVGMobject(\"user.svg\", fill_color=WHITE, stroke_color=WHITE).scale(0.5).to_edge(RIGHT)\n", " user_text = Text(\"User\", font_size=20).move_to(user_svg.get_bottom())\n", " user = VGroup(user_svg, user_text)\n", " \n", " title_text = Text(\"Latency\").scale(0.75).to_edge(UP)\n", " conclusion_text = Text(\"Latency is the time it takes for you to receive a response\").scale(0.5).to_edge(DOWN)\n", " self.play(FadeIn(llm_box), FadeIn(llm_text), FadeIn(user), Write(title_text), Write(conclusion_text))\n", "\n", " # Dynamic Packet Flow\n", " start_point = llm_box.get_right() + RIGHT * 0.5\n", " end_point = user_svg.get_left() + LEFT * 0.5\n", "\n", " packets = VGroup()\n", " \n", " # Timer setup\n", " timer = ValueTracker(0)\n", " timer_text = always_redraw(lambda: Text(f\"Latency: {timer.get_value():.2f}s\", font_size=24).to_corner(UR))\n", "\n", " self.add(timer_text)\n", "\n", " def create_packet(word):\n", " packet = Square(color=BLUE).scale(0.3).move_to(start_point)\n", " packet_text = Text(word, font_size=12).move_to(packet.get_center())\n", " packet_with_text = VGroup(packet, packet_text)\n", " packets.add(packet_with_text)\n", " self.add(packet_with_text)\n", " return packet_with_text.animate.move_to(end_point).set_rate_func(rate_functions.linear)\n", " \n", " for _ in range(rounds):\n", " for word in text_list:\n", " self.wait(0.2) # Adjust the wait time to change flow rate\n", " packet_animation = create_packet(word)\n", " self.play(packet_animation, timer.animate.set_value(timer.get_value() + 2), run_time=2)\n", " self.play(FadeOut(packets[-1]), run_time=0.5) # Fade out the last packet (the one that reached the user)\n", " timer.set_value(0) # Reset timer for next packet\n", "\n", " self.wait(1)\n", " self.play(FadeOut(packets))\n", "\n", " # Conclusion\n", " self.wait(2)\n", " self.play(FadeOut(conclusion_text), FadeOut(llm_box), FadeOut(llm_text), FadeOut(user), FadeOut(timer_text))\n" ] }, { "cell_type": "markdown", "id": "c894dbaf-021d-4441-9c0b-679bdca8ab8b", "metadata": {}, "source": [ "## Throughput" ] }, { "cell_type": "code", "execution_count": null, "id": "4d20b052-e155-412a-9f32-6ea1a890c361", "metadata": { "tags": [] }, "outputs": [], "source": [ "%%manim -qm EmojiScene\n", "from manim import *\n", "\n", "class EmojiScene(Scene):\n", " def construct(self):\n", " # Use Unicode escape sequence for the butterfly emoji\n", " text = Text(\"Butterfly: \\U0001F98B 🦋\", font=\"Apple Color Emoji\")\n", " self.add(text)\n", " self.play(FadeIn(text))\n", " self.wait(2)\n", "\n", "# Render the scene\n", "scene = EmojiScene()\n", "scene.render()\n" ] }, { "cell_type": "code", "execution_count": null, "id": "f0e03d7a-0db1-41aa-8a79-4a9f0f5615e7", "metadata": { "jupyter": { "outputs_hidden": true }, "tags": [] }, "outputs": [], "source": [ "%%manim -qm FontDemo\n", "from manim import *\n", "\n", "class FontDemo(Scene):\n", " def construct(self):\n", " font_names = [\n", " 'Academy Engraved LET', 'Adelle Sans Devanagari', 'AkayaKanadaka', 'AkayaTelivigala',\n", " 'Al Bayan', 'Al Nile', 'Al Tarikh', 'American Typewriter', 'Andale Mono', 'Annai MN',\n", " 'Apple Braille', 'Apple Chancery', 'Apple Color Emoji', 'Apple LiGothic', 'Apple LiSung',\n", " 'Apple SD Gothic Neo', 'Apple Symbols', 'AppleGothic', 'AppleMyungjo', 'Arial', 'Arial Black',\n", " 'Arial Hebrew', 'Arial Hebrew Scholar', 'Arial Narrow', 'Arial Rounded MT Bold', 'Arial Unicode MS',\n", " 'Arima Koshi', 'Arima Madurai', 'Avenir', 'Avenir Next', 'Avenir Next Condensed', 'Ayuthaya',\n", " 'BM Dohyeon', 'BM Hanna 11yrs Old', 'BM Hanna Air', 'BM Hanna Pro', 'BM Jua', 'BM Kirang Haerang',\n", " 'BM Yeonsung', 'Baghdad', 'Bai Jamjuree', 'Baloo 2', 'Baloo Bhai 2', 'Baloo Bhaijaan',\n", " 'Baloo Bhaina 2', 'Baloo Chettan 2', 'Baloo Da 2', 'Baloo Paaji 2', 'Baloo Tamma 2',\n", " 'Baloo Tammudu 2', 'Baloo Thambi 2', 'Bangla MN', 'Bangla Sangam MN', 'Baoli SC', 'Baoli TC',\n", " 'Baskerville', 'Beirut', 'BiauKai', 'Big Caslon', 'Bodoni 72', 'Bodoni 72 Oldstyle',\n", " 'Bodoni 72 Smallcaps', 'Bodoni Ornaments', 'Bradley Hand', 'Brush Script MT', 'Cambay Devanagari',\n", " 'Chakra Petch', 'Chalkboard', 'Chalkboard SE', 'Chalkduster', 'Charm', 'Charmonman', 'Charter',\n", " 'Cochin', 'Comic Sans MS', 'Copperplate', 'Corsiva Hebrew', 'Courier New', 'DIN Alternate',\n", " 'DIN Condensed', 'Damascus', 'DecoType Naskh', 'Devanagari MT', 'Devanagari Sangam MN', 'Didot',\n", " 'Diwan Kufi', 'Diwan Thuluth', 'Euphemia UCAS', 'Fahkwang', 'Farah', 'Farisi', 'Futura',\n", " 'GB18030 Bitmap', 'Galvji', 'Geeza Pro', 'Geneva', 'Georgia', 'Gill Sans', 'Gotu', 'Grantha Sangam MN',\n", " 'Graphik', 'Gujarati MT', 'Gujarati Sangam MN', 'GungSeo', 'Gurmukhi MN', 'Gurmukhi MT',\n", " 'Gurmukhi Sangam MN', 'Hannotate SC', 'Hannotate TC', 'HanziPen SC', 'HanziPen TC', 'HeadLineA',\n", " 'Hei', 'Heiti SC', 'Heiti TC', 'Helvetica', 'Helvetica Neue', 'Herculanum', 'Hiragino Maru Gothic ProN',\n", " 'Hiragino Mincho ProN', 'Hiragino Sans', 'Hiragino Sans CNS', 'Hiragino Sans GB', 'Hoefler Text',\n", " 'Hubballi', 'ITF Devanagari', 'ITF Devanagari Marathi', 'Impact', 'InaiMathi', 'Jaini', 'Jaini Purva',\n", " 'K2D', 'Kai', 'Kailasa', 'Kaiti SC', 'Kaiti TC', 'Kannada MN', 'Kannada Sangam MN', 'Katari',\n", " 'Kavivanar', 'Kefa', 'Khmer MN', 'Khmer Sangam MN', 'Klee', 'KoHo', 'Kodchasan', 'Kohinoor Bangla',\n", " 'Kohinoor Devanagari', 'Kohinoor Gujarati', 'Kohinoor Telugu', 'Kokonor', 'Krub', 'Krungthep',\n", " 'KufiStandardGK', 'Lahore Gurmukhi', 'Lantinghei SC', 'Lantinghei TC', 'Lao MN', 'Lao Sangam MN',\n", " 'Lava Devanagari', 'Lava Kannada', 'Lava Telugu', 'LiHei Pro', 'LiSong Pro', 'Libian SC', 'Libian TC',\n", " 'LingWai SC', 'LingWai TC', 'Lucida Grande', 'Luminari', 'Maku', 'Malayalam MN', 'Malayalam Sangam MN',\n", " 'Mali', 'Marker Felt', 'Menlo', 'Microsoft Sans Serif', 'Mishafi', 'Mishafi Gold', 'Modak', 'Monaco',\n", " 'Monaspace Argon', 'Monaspace Argon Var', 'Monaspace Krypton', 'Monaspace Krypton Var', 'Monaspace Neon',\n", " 'Monaspace Neon Var', 'Monaspace Radon', 'Monaspace Radon Var', 'Monaspace Xenon', 'Monaspace Xenon Var',\n", " 'Monospace', 'Mshtakan', 'Mukta', 'Mukta Mahee', 'Mukta Malar', 'Mukta Vaani', 'Muna', 'Myanmar MN',\n", " 'Myanmar Sangam MN', 'Nadeem', 'Nanum Brush Script', 'Nanum Gothic', 'Nanum Myeongjo', 'Nanum Pen Script',\n", " 'New Peninim MT', 'Niramit', 'Noteworthy', 'Noto Nastaliq Urdu', 'Noto Sans Batak', 'Noto Sans Kannada',\n", " 'Noto Sans Myanmar', 'Noto Sans NKo', 'Noto Sans Oriya', 'Noto Sans Tagalog', 'Noto Serif Kannada',\n", " 'Noto Serif Myanmar', 'October Compressed Devanagari', 'October Compressed Tamil',\n", " 'October Condensed Devanagari', 'October Condensed Tamil', 'October Devanagari', 'October Tamil', 'Optima',\n", " 'Oriya MN', 'Oriya Sangam MN', 'Osaka', 'PCMyungjo', 'PSL Ornanong Pro', 'PT Mono', 'PT Sans',\n", " 'PT Sans Caption', 'PT Sans Narrow', 'PT Serif', 'PT Serif Caption', 'Padyakke Expanded One', 'Palatino',\n", " 'Papyrus', 'Party LET', 'Phosphate', 'PilGi', 'PingFang HK', 'PingFang SC', 'PingFang TC',\n", " 'Plantagenet Cherokee', 'Raanana', 'Rockwell', 'STFangsong', 'STHeiti', 'STIX Two Math', 'STIX Two Text',\n", " 'STKaiti', 'STSong', 'Sama Devanagari', 'Sama Gujarati', 'Sama Gurmukhi', 'Sama Kannada', 'Sama Malayalam',\n", " 'Sama Tamil', 'Sana', 'Sans', 'Sarabun', 'Sathu', 'Savoye LET', 'Serif', 'Shobhika', 'Shree Devanagari 714',\n", " 'SignPainter', 'Silom', 'SimSong', 'Sinhala MN', 'Sinhala Sangam MN', 'Skia', 'Snell Roundhand',\n", " 'Songti SC', 'Songti TC', 'Srisakdi', 'Sukhumvit Set', 'Symbol', 'Tahoma', 'Tamil MN', 'Tamil Sangam MN',\n", " 'Telugu MN', 'Telugu Sangam MN', 'Thonburi', 'Times New Roman', 'Tiro Bangla', 'Tiro Devanagari Hindi',\n", " 'Tiro Devanagari Marathi', 'Tiro Devanagari Sanskrit', 'Tiro Gurmukhi', 'Tiro Kannada', 'Tiro Tamil',\n", " 'Tiro Telugu', 'Toppan Bunkyu Gothic', 'Toppan Bunkyu Midashi Gothic', 'Toppan Bunkyu Midashi Mincho',\n", " 'Toppan Bunkyu Mincho', 'Trattatello', 'Trebuchet MS', 'Tsukushi A Round Gothic', 'Tsukushi B Round Gothic',\n", " 'Verdana', 'Waseem', 'Wawati SC', 'Wawati TC', 'Webdings', 'Wingdings', 'Wingdings 2', 'Wingdings 3',\n", " 'Xingkai SC', 'Xingkai TC', 'YuGothic', 'YuKyokasho', 'YuKyokasho Yoko', 'YuMincho', 'YuMincho +36p Kana',\n", " 'Yuanti SC', 'Yuanti TC', 'Yuppy SC', 'Yuppy TC', 'Zapf Dingbats', 'Zapfino', 'cursive', 'fantasy', 'system-ui'\n", " ]\n", "\n", " texts = []\n", " for font_name in font_names:\n", " text_part = Text(f\"{font_name}: 🦋 \\U0001F98B\", font=font_name).scale(0.75)\n", " combined_text = VGroup(text_part).arrange(RIGHT, buff=0.1)\n", " texts.append(combined_text)\n", "\n", " for i in range(0, len(texts), 15):\n", " batch = VGroup(*texts[i:i+15]).arrange(DOWN, buff=0.5)\n", " batch.scale_to_fit_height(config.frame_height - 1)\n", " self.play(FadeIn(batch))\n", " self.wait(1)\n", " self.play(FadeOut(batch))\n", "\n", " self.wait(2)\n" ] }, { "cell_type": "code", "execution_count": null, "id": "37ad0a6c-e068-4ace-b31f-2c8c1eb8f52b", "metadata": { "tags": [] }, "outputs": [], "source": [ "%%manim -qm ThroughputVisualization\n", "\n", "from manim import *\n", "\n", "class ThroughputVisualization(Scene):\n", " text = [\"His hands can't hit what he can't see\", \n", " \"Float like a 🦋, sting like a bee\",\n", " \"I'm so mean, I make medic -ine sick.\",\n", " \"Suffer now and retire as a champ -ion\"]\n", " batch_size = 4\n", " rounds = 1\n", "\n", " def construct(self):\n", " # Split text into words\n", " words = [sentence.split() for sentence in self.text]\n", " max_len = max(len(sentence) for sentence in words)\n", " \n", " # Extend shorter sentences with empty strings to match the longest sentence\n", " for sentence in words:\n", " sentence.extend([''] * (max_len - len(sentence)))\n", " \n", " # Transpose to get words from each sentence in each pass\n", " transposed_words = list(map(list, zip(*words)))\n", "\n", " # Setup LLM and user\n", " llm_box = Rectangle(width=2, height=1).set_fill(GREEN, opacity=0.5).set_stroke(GREEN, width=2).to_edge(LEFT).shift(DOWN)\n", " llm_text = Text(\"LLM\", color=WHITE).move_to(llm_box.get_center())\n", " user_svg = SVGMobject(\"user.svg\", fill_color=WHITE, stroke_color=WHITE).scale(0.5).to_edge(RIGHT).shift(DOWN)\n", " user_text = Text(\"User\", font_size=20).move_to(user_svg.get_bottom())\n", " user = VGroup(user_svg, user_text)\n", " \n", " title_text = Text(\"Throughput\").scale(0.75).to_edge(UP)\n", " conclusion_text = Text(\"Throughput is the amount of data processed in a given time\").scale(0.5).to_edge(DOWN)\n", " self.play(FadeIn(llm_box), FadeIn(llm_text), FadeIn(user), Write(title_text), Write(conclusion_text))\n", "\n", " # Dynamic Packet Flow\n", " start_point = llm_box.get_right() + RIGHT * 0.5\n", " end_point = user_svg.get_left() + LEFT * 1\n", " storage_start = start_point + UP * 2.5 + LEFT * 1.5\n", " \n", " # Define initial storage positions in a block formation\n", " storage_positions = [\n", " storage_start,\n", " storage_start + RIGHT * 6,\n", " storage_start + DOWN * 1,\n", " storage_start + RIGHT * 6 + DOWN * 1,\n", " ]\n", " storage_offsets = [0, 0, 0, 0] # Initialize offsets for each storage position\n", "\n", " packets = VGroup()\n", " \n", " # Timer setup\n", " timer = ValueTracker(0)\n", " timer_text = always_redraw(lambda: Text(f\"Time: {timer.get_value():.2f}s\\nThroughput: 4 Tokens/s\", font_size=18).to_corner(UR))\n", "\n", " self.add(timer_text)\n", "\n", " def create_packet_group(words):\n", " packet_group = VGroup()\n", " for i, word in enumerate(words):\n", " row, col = divmod(i, 2)\n", " packet = Square(color=GREEN).scale(0.3).move_to(start_point + RIGHT * col * 0.6 + DOWN * row * 0.6)\n", " packet_text = Text(word, font_size=12).move_to(packet.get_center())\n", " packet_with_text = VGroup(packet, packet_text)\n", " packet_group.add(packet_with_text)\n", " packet_group.next_to(llm_box)\n", " return packet_group\n", "\n", " for _ in range(self.rounds):\n", " for word_group in transposed_words:\n", " if any(word_group): # Check if there are any non-empty words\n", " packet_group = create_packet_group(word_group)\n", " packets.add(packet_group)\n", " self.play(FadeIn(packet_group))\n", " self.play(packet_group.animate.move_to(end_point), timer.animate.set_value(timer.get_value() + 1), run_time=1)\n", "\n", " # Determine which storage position to use\n", " new_storage_position = []\n", " for i, packet in enumerate(packet_group):\n", " storage_index = i % self.batch_size\n", " storage_position = storage_positions[storage_index] + RIGHT * storage_offsets[storage_index]\n", " new_storage_position.append(packet.animate.move_to(storage_position))\n", " storage_offsets[storage_index] += 0.6 # Adjust based on the width of packet group\n", " self.play(*new_storage_position, run_time=0.5)\n", "\n", " self.wait(0.1) # Adjust the wait time to change flow rate\n", " timer.set_value(0) # Reset timer for next batch\n", "\n", " self.wait(1)\n", "\n", " # Conclusion\n", " self.wait(2)\n", " self.play(FadeOut(packets), FadeOut(conclusion_text), FadeOut(llm_box), FadeOut(llm_text), FadeOut(user), FadeOut(timer_text))\n" ] }, { "cell_type": "code", "execution_count": null, "id": "0d487ddf-4725-497e-a37b-2d9b6f69338f", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.8" } }, "nbformat": 4, "nbformat_minor": 5 }