Buckets:

download
raw
45 kB
<meta charset="utf-8" /><meta name="hf:doc:metadata" content="{&quot;title&quot;:&quot;Profiler&quot;,&quot;local&quot;:&quot;profiler&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Using profiler to analyze execution time&quot;,&quot;local&quot;:&quot;using-profiler-to-analyze-execution-time&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Using profiler to analyze memory consumption&quot;,&quot;local&quot;:&quot;using-profiler-to-analyze-memory-consumption&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Exporting chrome trace&quot;,&quot;local&quot;:&quot;exporting-chrome-trace&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Using Profiler to Analyze Long-Running Jobs&quot;,&quot;local&quot;:&quot;using-profiler-to-analyze-long-running-jobs&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;FLOPS&quot;,&quot;local&quot;:&quot;flops&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Conclusion and Further Information&quot;,&quot;local&quot;:&quot;conclusion-and-further-information&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2}],&quot;depth&quot;:1}">
<link href="/docs/accelerate/pr_4021/en/_app/immutable/assets/0.e3b0c442.css" rel="modulepreload">
<link rel="modulepreload" href="/docs/accelerate/pr_4021/en/_app/immutable/entry/start.8a49e72b.js">
<link rel="modulepreload" href="/docs/accelerate/pr_4021/en/_app/immutable/chunks/scheduler.b9285784.js">
<link rel="modulepreload" href="/docs/accelerate/pr_4021/en/_app/immutable/chunks/singletons.7547c222.js">
<link rel="modulepreload" href="/docs/accelerate/pr_4021/en/_app/immutable/chunks/index.6d423e5c.js">
<link rel="modulepreload" href="/docs/accelerate/pr_4021/en/_app/immutable/chunks/paths.d42c9205.js">
<link rel="modulepreload" href="/docs/accelerate/pr_4021/en/_app/immutable/entry/app.1df4d18e.js">
<link rel="modulepreload" href="/docs/accelerate/pr_4021/en/_app/immutable/chunks/preload-helper.b0bd19d1.js">
<link rel="modulepreload" href="/docs/accelerate/pr_4021/en/_app/immutable/chunks/index.26bc89a1.js">
<link rel="modulepreload" href="/docs/accelerate/pr_4021/en/_app/immutable/nodes/0.0e7c56e8.js">
<link rel="modulepreload" href="/docs/accelerate/pr_4021/en/_app/immutable/chunks/each.e59479a4.js">
<link rel="modulepreload" href="/docs/accelerate/pr_4021/en/_app/immutable/nodes/55.7f7cf546.js">
<link rel="modulepreload" href="/docs/accelerate/pr_4021/en/_app/immutable/chunks/MermaidChart.svelte_svelte_type_style_lang.7a0ae628.js">
<link rel="modulepreload" href="/docs/accelerate/pr_4021/en/_app/immutable/chunks/CodeBlock.844ff9c3.js">
<link rel="modulepreload" href="/docs/accelerate/pr_4021/en/_app/immutable/chunks/HfOption.76c7ca3e.js"><!-- HEAD_svelte-u9bgzb_START --><meta name="hf:doc:metadata" content="{&quot;title&quot;:&quot;Profiler&quot;,&quot;local&quot;:&quot;profiler&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Using profiler to analyze execution time&quot;,&quot;local&quot;:&quot;using-profiler-to-analyze-execution-time&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Using profiler to analyze memory consumption&quot;,&quot;local&quot;:&quot;using-profiler-to-analyze-memory-consumption&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Exporting chrome trace&quot;,&quot;local&quot;:&quot;exporting-chrome-trace&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Using Profiler to Analyze Long-Running Jobs&quot;,&quot;local&quot;:&quot;using-profiler-to-analyze-long-running-jobs&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;FLOPS&quot;,&quot;local&quot;:&quot;flops&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Conclusion and Further Information&quot;,&quot;local&quot;:&quot;conclusion-and-further-information&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2}],&quot;depth&quot;:1}"><!-- HEAD_svelte-u9bgzb_END --> <p></p> <div class="items-center shrink-0 min-w-[100px] max-sm:min-w-[50px] justify-end ml-auto flex" style="float: right; margin-left: 10px; display: inline-flex; position: relative; z-index: 10;"><div class="inline-flex rounded-md max-sm:rounded-sm"><button class="inline-flex items-center gap-1 h-7 max-sm:h-7 px-2 max-sm:px-1.5 text-sm font-medium text-gray-800 border border-r-0 rounded-l-md max-sm:rounded-l-sm border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-live="polite"><span class="inline-flex items-center justify-center rounded-md p-0.5 max-sm:p-0 hover:text-gray-800 dark:hover:text-gray-200"><svg class="sm:size-3.5 size-3" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg></span> <span>Copy page</span></button> <button class="inline-flex items-center justify-center w-6 max-sm:w-5 h-7 max-sm:h-7 disabled:pointer-events-none text-sm text-gray-500 hover:text-gray-700 dark:hover:text-white rounded-r-md max-sm:rounded-r-sm border border-l transition border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-haspopup="menu" aria-expanded="false" aria-label="Open copy menu"><svg class="transition-transform text-gray-400 overflow-visible sm:size-3.5 size-3 rotate-0" width="1em" height="1em" viewBox="0 0 12 7" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 1L6 6L11 1" stroke="currentColor"></path></svg></button></div> </div> <h1 class="relative group"><a id="profiler" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#profiler"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Profiler</span></h1> <p data-svelte-h="svelte-nolygo">Profiler is a tool that allows the collection of performance metrics during training and inference. Profiler’s context manager API can be used to better understand what model operators are the most expensive, examine their input shapes and stack traces, study device kernel activity, and visualize the execution trace. It provides insights into the performance of your model, allowing you to optimize and improve it.</p> <p data-svelte-h="svelte-mqipw7">This guide explains how to use PyTorch Profiler to measure the time and memory consumption of the model’s operators and how to integrate this with Accelerate. We will cover various use cases and provide examples for each.</p> <h2 class="relative group"><a id="using-profiler-to-analyze-execution-time" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#using-profiler-to-analyze-execution-time"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Using profiler to analyze execution time</span></h2> <p data-svelte-h="svelte-rec50t">Profiler allows one to check which operators were called during the execution of a code range wrapped with a profiler context manager.</p> <p data-svelte-h="svelte-556cz1">Let’s see how we can use profiler to analyze the execution time:</p> <div class="flex space-x-2 items-center my-1.5 mr-8 h-7 !pl-0 -mx-3 md:mx-0"><div class="flex items-center border rounded-lg px-1.5 py-1 leading-none select-none text-smd border-gray-800 bg-black dark:bg-gray-700 text-white">PyTorch </div><div class="flex items-center border rounded-lg px-1.5 py-1 leading-none select-none text-smd text-gray-500 cursor-pointer opacity-90 hover:text-gray-700 dark:hover:text-gray-200 hover:shadow-sm">Accelerate </div></div> <div class="language-select"><div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">import</span> torch
<span class="hljs-keyword">import</span> torchvision.models <span class="hljs-keyword">as</span> models
<span class="hljs-keyword">from</span> torch.profiler <span class="hljs-keyword">import</span> profile, record_function, ProfilerActivity
model = models.resnet18()
inputs = torch.randn(<span class="hljs-number">5</span>, <span class="hljs-number">3</span>, <span class="hljs-number">224</span>, <span class="hljs-number">224</span>)
<span class="hljs-keyword">with</span> profile(activities=[ProfilerActivity.CPU], record_shapes=<span class="hljs-literal">True</span>) <span class="hljs-keyword">as</span> prof:
model(inputs)
<span class="hljs-built_in">print</span>(prof.key_averages().table(sort_by=<span class="hljs-string">&quot;cpu_time_total&quot;</span>, row_limit=<span class="hljs-number">10</span>))<!-- HTML_TAG_END --></pre></div> </div> <p data-svelte-h="svelte-1nltvv4">The resulting table output (omitting some columns):</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-params">---------------------------------</span> <span class="hljs-params">------------</span> <span class="hljs-params">------------</span> <span class="hljs-params">------------</span> <span class="hljs-params">------------</span>
Name Self CPU CPU total CPU time avg <span class="hljs-comment"># of Calls </span>
<span class="hljs-params">---------------------------------</span> <span class="hljs-params">------------</span> <span class="hljs-params">------------</span> <span class="hljs-params">------------</span> <span class="hljs-params">------------</span>
aten:<span class="hljs-function">:conv2d</span> 171.000us 52.260ms 2.613ms 20
aten:<span class="hljs-function">:convolution</span> 227.000us 52.089ms 2.604ms 20
aten:<span class="hljs-function">:_convolution</span> 270.000us 51.862ms 2.593ms 20
aten:<span class="hljs-function">:mkldnn_convolution</span> 51.273ms 51.592ms 2.580ms 20
aten:<span class="hljs-function">:batch_norm</span> 118.000us 7.059ms 352.950us 20
aten:<span class="hljs-function">:_batch_norm_impl_index</span> 315.000us 6.941ms 347.050us 20
aten:<span class="hljs-function">:native_batch_norm</span> 6.305ms 6.599ms 329.950us 20
aten:<span class="hljs-function">:max_pool2d</span> 40.000us 4.008ms 4.008ms 1
aten:<span class="hljs-function">:max_pool2d_with_indices</span> 3.968ms 3.968ms 3.968ms 1
aten:<span class="hljs-function">:add_</span> 780.000us 780.000us 27.857us 28
<span class="hljs-params">---------------------------------</span> <span class="hljs-params">------------</span> <span class="hljs-params">------------</span> <span class="hljs-params">------------</span> <span class="hljs-params">------------</span>
Self CPU time total: 67.016ms<!-- HTML_TAG_END --></pre></div> <p data-svelte-h="svelte-6rbdvd">To get a finer granularity of results and include operator input shapes, pass <code>group_by_input_shape=True</code> (note: this requires running the profiler with <code>record_shapes=True</code>):</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-built_in">print</span>(prof.key_averages(group_by_input_shape=<span class="hljs-literal">True</span>).table(sort_by=<span class="hljs-string">&quot;cpu_time_total&quot;</span>, row_limit=<span class="hljs-number">10</span>))<!-- HTML_TAG_END --></pre></div> <h2 class="relative group"><a id="using-profiler-to-analyze-memory-consumption" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#using-profiler-to-analyze-memory-consumption"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Using profiler to analyze memory consumption</span></h2> <p data-svelte-h="svelte-1eenghb">Profiler can also show the amount of memory (used by the model’s tensors) that was allocated (or released) during the execution of the model’s operators. To enable memory profiling functionality pass <code>profile_memory=True</code>.</p> <div class="flex space-x-2 items-center my-1.5 mr-8 h-7 !pl-0 -mx-3 md:mx-0"><div class="flex items-center border rounded-lg px-1.5 py-1 leading-none select-none text-smd border-gray-800 bg-black dark:bg-gray-700 text-white">PyTorch </div><div class="flex items-center border rounded-lg px-1.5 py-1 leading-none select-none text-smd text-gray-500 cursor-pointer opacity-90 hover:text-gray-700 dark:hover:text-gray-200 hover:shadow-sm">Accelerate </div></div> <div class="language-select"><div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->model = models.resnet18()
inputs = torch.randn(<span class="hljs-number">5</span>, <span class="hljs-number">3</span>, <span class="hljs-number">224</span>, <span class="hljs-number">224</span>)
<span class="hljs-keyword">with</span> profile(activities=[ProfilerActivity.CPU],
profile_memory=<span class="hljs-literal">True</span>, record_shapes=<span class="hljs-literal">True</span>) <span class="hljs-keyword">as</span> prof:
model(inputs)
<span class="hljs-built_in">print</span>(prof.key_averages().table(sort_by=<span class="hljs-string">&quot;self_cpu_memory_usage&quot;</span>, row_limit=<span class="hljs-number">10</span>))<!-- HTML_TAG_END --></pre></div> </div> <p data-svelte-h="svelte-1nltvv4">The resulting table output (omitting some columns):</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->--------------------------------- ------------ ------------ ------------
Name CPU Mem Self CPU Mem <span class="hljs-comment"># of Calls </span>
--------------------------------- ------------ ------------ ------------
aten::empty 94.85 Mb 94.85 Mb <span class="hljs-number"> 205 </span>
aten::max_pool2d_with_indices 11.48 Mb 11.48 Mb <span class="hljs-number"> 1 </span>
aten::addmm 19.53 Kb 19.53 Kb <span class="hljs-number"> 1 </span>
aten::mean 10.00 Kb 10.00 Kb <span class="hljs-number"> 1 </span>
aten::empty_strided <span class="hljs-number"> 492 </span>b <span class="hljs-number"> 492 </span>b <span class="hljs-number"> 5 </span>
aten::cat <span class="hljs-number"> 240 </span>b <span class="hljs-number"> 240 </span>b <span class="hljs-number"> 6 </span>
aten::abs <span class="hljs-number"> 480 </span>b <span class="hljs-number"> 240 </span>b <span class="hljs-number"> 4 </span>
aten::masked_select <span class="hljs-number"> 120 </span>b <span class="hljs-number"> 112 </span>b <span class="hljs-number"> 1 </span>
aten::ne <span class="hljs-number"> 61 </span>b <span class="hljs-number"> 53 </span>b <span class="hljs-number"> 3 </span>
aten::eq <span class="hljs-number"> 30 </span>b <span class="hljs-number"> 30 </span>b <span class="hljs-number"> 1 </span>
--------------------------------- ------------ ------------ ------------
Self CPU time total: 69.332ms<!-- HTML_TAG_END --></pre></div> <h2 class="relative group"><a id="exporting-chrome-trace" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#exporting-chrome-trace"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Exporting chrome trace</span></h2> <p data-svelte-h="svelte-r8y8s9">You can examine the sequence of profiled operators and CUDA kernels in Chrome trace viewer (<code>chrome://tracing</code>):</p> <p data-svelte-h="svelte-14g38nf"><img src="https://github.com/huggingface/accelerate/assets/100389977/5acb193f-6d11-4f7b-9873-c600c19e8172" alt="profile_export"></p> <div class="flex space-x-2 items-center my-1.5 mr-8 h-7 !pl-0 -mx-3 md:mx-0"><div class="flex items-center border rounded-lg px-1.5 py-1 leading-none select-none text-smd border-gray-800 bg-black dark:bg-gray-700 text-white">PyTorch </div><div class="flex items-center border rounded-lg px-1.5 py-1 leading-none select-none text-smd text-gray-500 cursor-pointer opacity-90 hover:text-gray-700 dark:hover:text-gray-200 hover:shadow-sm">Accelerate </div></div> <div class="language-select"><div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->model = models.resnet18().cuda()
inputs = torch.randn(<span class="hljs-number">5</span>, <span class="hljs-number">3</span>, <span class="hljs-number">224</span>, <span class="hljs-number">224</span>).cuda()
<span class="hljs-keyword">with</span> profile(activities=[ProfilerActivity.CPU, ProfilerActivity.CUDA]) <span class="hljs-keyword">as</span> prof:
model(inputs)
prof.export_chrome_trace(<span class="hljs-string">&quot;trace.json&quot;</span>)<!-- HTML_TAG_END --></pre></div> </div> <h2 class="relative group"><a id="using-profiler-to-analyze-long-running-jobs" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#using-profiler-to-analyze-long-running-jobs"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Using Profiler to Analyze Long-Running Jobs</span></h2> <p data-svelte-h="svelte-voqhk0">Profiler offers an additional API to handle long-running jobs (such as training loops). Tracing all of the execution can be slow and result in very large trace files. To avoid this, use optional arguments:</p> <ul data-svelte-h="svelte-zcfpqf"><li><code>schedule_option</code>: Scheduling options allow you to control when profiling is active. This is useful for long-running jobs to avoid collecting too much data. Available keys are <code>wait</code>, <code>warmup</code>, <code>active</code>, <code>repeat</code> and <code>skip_first</code>. The profiler will skip the first <code>skip_first</code> steps, then wait for <code>wait</code> steps, then do the warmup for the next <code>warmup</code> steps, then do the active recording for the next <code>active</code> steps and then repeat the cycle starting with <code>wait</code> steps. The optional number of cycles is specified with the <code>repeat</code> parameter, the zero value means that the cycles will continue until the profiling is finished.</li> <li><code>on_trace_ready</code>: specifies a function that takes a reference to the profiler as an input and is called by the profiler each time the new trace is ready.</li></ul> <p data-svelte-h="svelte-1idin3s">To illustrate how the API works, consider the following example:</p> <div class="flex space-x-2 items-center my-1.5 mr-8 h-7 !pl-0 -mx-3 md:mx-0"><div class="flex items-center border rounded-lg px-1.5 py-1 leading-none select-none text-smd border-gray-800 bg-black dark:bg-gray-700 text-white">PyTorch </div><div class="flex items-center border rounded-lg px-1.5 py-1 leading-none select-none text-smd text-gray-500 cursor-pointer opacity-90 hover:text-gray-700 dark:hover:text-gray-200 hover:shadow-sm">Accelerate </div></div> <div class="language-select"><div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">from</span> torch.profiler <span class="hljs-keyword">import</span> schedule
my_schedule = schedule(
skip_first=<span class="hljs-number">1</span>,
wait=<span class="hljs-number">5</span>,
warmup=<span class="hljs-number">1</span>,
active=<span class="hljs-number">3</span>,
repeat=<span class="hljs-number">2</span>
)
<span class="hljs-keyword">def</span> <span class="hljs-title function_">trace_handler</span>(<span class="hljs-params">p</span>):
output = p.key_averages().table(sort_by=<span class="hljs-string">&quot;self_cuda_time_total&quot;</span>, row_limit=<span class="hljs-number">10</span>)
<span class="hljs-built_in">print</span>(output)
p.export_chrome_trace(<span class="hljs-string">&quot;/tmp/trace_&quot;</span> + <span class="hljs-built_in">str</span>(p.step_num) + <span class="hljs-string">&quot;.json&quot;</span>)
<span class="hljs-keyword">with</span> profile(
activities=[ProfilerActivity.CPU, ProfilerActivity.CUDA],
schedule=my_schedule,
on_trace_ready=trace_handler
) <span class="hljs-keyword">as</span> p:
<span class="hljs-keyword">for</span> idx <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">8</span>):
model(inputs)
p.step()<!-- HTML_TAG_END --></pre></div> </div> <h2 class="relative group"><a id="flops" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#flops"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>FLOPS</span></h2> <p data-svelte-h="svelte-wx7pol">Use formula to estimate the FLOPs (floating point operations) of specific operators (matrix multiplication and 2D convolution).</p> <p data-svelte-h="svelte-yw0di5">To measure floating-point operations (FLOPS):</p> <div class="flex space-x-2 items-center my-1.5 mr-8 h-7 !pl-0 -mx-3 md:mx-0"><div class="flex items-center border rounded-lg px-1.5 py-1 leading-none select-none text-smd border-gray-800 bg-black dark:bg-gray-700 text-white">PyTorch </div><div class="flex items-center border rounded-lg px-1.5 py-1 leading-none select-none text-smd text-gray-500 cursor-pointer opacity-90 hover:text-gray-700 dark:hover:text-gray-200 hover:shadow-sm">Accelerate </div></div> <div class="language-select"><div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">with</span> profile(
activities=[ProfilerActivity.CPU, ProfilerActivity.CUDA],
with_flops=<span class="hljs-literal">True</span>
) <span class="hljs-keyword">as</span> prof:
model(inputs)
<span class="hljs-built_in">print</span>(prof.key_averages().table(sort_by=<span class="hljs-string">&quot;flops&quot;</span>, row_limit=<span class="hljs-number">10</span>))<!-- HTML_TAG_END --></pre></div> </div> <p data-svelte-h="svelte-1nltvv4">The resulting table output (omitting some columns):</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-literal">-------------------------------------------------------</span> <span class="hljs-literal">------------</span> <span class="hljs-literal">------------</span> <span class="hljs-literal">------------</span>
<span class="hljs-comment">Name Self CPU Self CUDA Total FLOPs</span>
<span class="hljs-literal">-------------------------------------------------------</span> <span class="hljs-literal">------------</span> <span class="hljs-literal">------------</span> <span class="hljs-literal">------------</span>
<span class="hljs-comment">aten::conv2d 197</span><span class="hljs-string">.</span><span class="hljs-comment">000us 0</span><span class="hljs-string">.</span><span class="hljs-comment">000us 18135613440</span><span class="hljs-string">.</span><span class="hljs-comment">000</span>
<span class="hljs-comment">aten::addmm 103</span><span class="hljs-string">.</span><span class="hljs-comment">000us 17</span><span class="hljs-string">.</span><span class="hljs-comment">000us 5120000</span><span class="hljs-string">.</span><span class="hljs-comment">000</span>
<span class="hljs-comment">aten::mul 29</span><span class="hljs-string">.</span><span class="hljs-comment">000us 2</span><span class="hljs-string">.</span><span class="hljs-comment">000us 30</span><span class="hljs-string">.</span><span class="hljs-comment">000</span>
<span class="hljs-comment">aten::convolution 409</span><span class="hljs-string">.</span><span class="hljs-comment">000us 0</span><span class="hljs-string">.</span><span class="hljs-comment">000us</span> <span class="hljs-literal">--</span>
<span class="hljs-comment">aten::_convolution 253</span><span class="hljs-string">.</span><span class="hljs-comment">000us 0</span><span class="hljs-string">.</span><span class="hljs-comment">000us</span> <span class="hljs-literal">--</span>
<span class="hljs-comment">aten::cudnn_convolution 5</span><span class="hljs-string">.</span><span class="hljs-comment">465ms 2</span><span class="hljs-string">.</span><span class="hljs-comment">970ms</span> <span class="hljs-literal">--</span>
<span class="hljs-comment">cudaEventRecord 138</span><span class="hljs-string">.</span><span class="hljs-comment">000us 0</span><span class="hljs-string">.</span><span class="hljs-comment">000us</span> <span class="hljs-literal">--</span>
<span class="hljs-comment">cudaStreamIsCapturing 43</span><span class="hljs-string">.</span><span class="hljs-comment">000us 0</span><span class="hljs-string">.</span><span class="hljs-comment">000us</span> <span class="hljs-literal">--</span>
<span class="hljs-comment">cudaStreamGetPriority 40</span><span class="hljs-string">.</span><span class="hljs-comment">000us 0</span><span class="hljs-string">.</span><span class="hljs-comment">000us</span> <span class="hljs-literal">--</span>
<span class="hljs-comment">cudaDeviceGetStreamPriorityRange 10</span><span class="hljs-string">.</span><span class="hljs-comment">000us 0</span><span class="hljs-string">.</span><span class="hljs-comment">000us</span> <span class="hljs-literal">--</span>
<span class="hljs-literal">-------------------------------------------------------</span> <span class="hljs-literal">------------</span> <span class="hljs-literal">------------</span> <span class="hljs-literal">------------</span>
<span class="hljs-comment">Self CPU time total: 21</span><span class="hljs-string">.</span><span class="hljs-comment">938ms</span>
<span class="hljs-comment">Self CUDA time total: 4</span><span class="hljs-string">.</span><span class="hljs-comment">165ms</span><!-- HTML_TAG_END --></pre></div> <h2 class="relative group"><a id="conclusion-and-further-information" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#conclusion-and-further-information"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Conclusion and Further Information</span></h2> <p data-svelte-h="svelte-ubv7yt">PyTorch Profiler is a powerful tool for analyzing the performance of your models. By integrating it with Accelerate, you can easily profile your models and gain insights into their performance, helping you to optimize and improve them.</p> <p data-svelte-h="svelte-15zce5a">For more detailed information, refer to the <a href="https://pytorch.org/docs/stable/profiler.html" rel="nofollow">PyTorch Profiler documentation</a>.</p> <a class="!text-gray-400 !no-underline text-sm flex items-center not-prose mt-4" href="https://github.com/huggingface/accelerate/blob/main/docs/source/usage_guides/profiler.md" target="_blank"><svg class="mr-1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M31,16l-7,7l-1.41-1.41L28.17,16l-5.58-5.59L24,9l7,7z"></path><path d="M1,16l7-7l1.41,1.41L3.83,16l5.58,5.59L8,23l-7-7z"></path><path d="M12.419,25.484L17.639,6.552l1.932,0.518L14.351,26.002z"></path></svg> <span data-svelte-h="svelte-zjs2n5"><span class="underline">Update</span> on GitHub</span></a> <p></p>
<script>
{
__sveltekit_1q7nz6m = {
assets: "/docs/accelerate/pr_4021/en",
base: "/docs/accelerate/pr_4021/en",
env: {}
};
const element = document.currentScript.parentElement;
const data = [null,null];
Promise.all([
import("/docs/accelerate/pr_4021/en/_app/immutable/entry/start.8a49e72b.js"),
import("/docs/accelerate/pr_4021/en/_app/immutable/entry/app.1df4d18e.js")
]).then(([kit, app]) => {
kit.start(app, element, {
node_ids: [0, 55],
data,
form: null,
error: null
});
});
}
</script>

Xet Storage Details

Size:
45 kB
·
Xet hash:
8d839112ffee5b2fbbce1e94a0f71a427d26b9de80db59aeec9d44a29bcd2c11

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.