{
    "componentChunkName": "component---packages-gatsby-theme-blog-core-src-templates-post-query-js",
    "path": "/blog/2026/04/setup-fvdb-ubuntu-22-04/",
    "result": {"data":{"post":{"id":"25543cf5-bbb7-5c2c-82b5-295f54a1f558","title":"Setting up Ubuntu 22.04 to run fVDB Reality Capture","date":"April 09, 2026","excerpt":"Got a macOS and want to do Gaussian splatting? Hosted GPU as a service is the best way!","body":"var _excluded = [\"components\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"Setting up Ubuntu 22.04 to run fVDB Reality Capture\",\n  \"date\": \"2026-04-09T00:00:00.000Z\",\n  \"excerpt\": \"Got a macOS and want to do Gaussian splatting? Hosted GPU as a service is the best way!\",\n  \"image\": \"./house-splat.png\",\n  \"socialImage\": \"./house-splat.png\",\n  \"tags\": [\"ubuntu\", \"gaussian-splat\"]\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, _excluded);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-html\"\n  }, \"<!-- This post is a work in progress, please excuse the mess -->\\n\")), mdx(\"p\", null, \"I found myself wanting to dabble in Gaussian splats but at the same time not wanting to have to buy a GPU (with prices how they are!)\\nso instead of following the typical flow for Gaussian splatters' and starting on a gaming GPU and working my way up to hosted\\nGPU I have decided to jump directly to hosted GPUs!\"), mdx(\"p\", null, \"For this process I have gone with \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://www.paperspace.com\"\n  }, \"paperspace\"), \" however any GPU as a service host should work\\nall we need is ssh access, you will find that you can only really gain access to Gaming computer as a service providers without\\napproval from the IaaS providers like paperspace/aws/azure but I have found their offerings to be a bit too expensive for\\nwhat you get + typically they are windows boxes (so that won't work for fVDB). Just open a support ticket and get your\\naccess, you will have to wait a day but that's just a part of the cost of getting good access.\"), mdx(\"h2\", {\n    \"id\": \"setting-up-the-box\"\n  }, \"setting up the box\"), mdx(\"p\", null, \"as soon as you boot up the box the first thing is to start updating the box and installing software:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"sudo apt update\\n\")), mdx(\"p\", null, \"Now we will need to install the nvidia GPU drivers, to do so we will run \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"sudo ubuntu-drivers devices\"), \" and find\\nthe row which has \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"recommended\"), \" on it, it will look something like so:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"driver   : nvidia-driver-580 - distro non-free recommended\\ndriver   : nvidia-driver-535 - distro non-free\\ndriver   : nvidia-driver-570-server-open - distro non-free\\ndriver   : nvidia-driver-570-open - distro non-free\\n\")), mdx(\"p\", null, \"in the above example we want \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"nvidia-driver-580\"), \", so we will install the drivers like so:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"sudo apt install -y nvidia-driver-580\\nsudo reboot\\n\")), mdx(\"p\", null, \"after this completes you want to restart the machine which is why I have included the reboot command.\\nDon't forget that you need to place the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"recommended\"), \" driver after the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"-y\"), \" and not what my example showed.\"), mdx(\"p\", null, \"From there we will see what cuda is supported by these drivers with the following command:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"nvidia-smi\\nWed Apr  8 16:59:16 2026\\n+-----------------------------------------------------------------------------------------+\\n| NVIDIA-SMI 580.126.09             Driver Version: 580.126.09     CUDA Version: 13.0     |\\n+-----------------------------------------+------------------------+----------------------+\\n| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |\\n| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |\\n|                                         |                        |               MIG M. |\\n|=========================================+========================+======================|\\n|   0  NVIDIA RTX A4000               Off |   00000000:00:05.0 Off |                  Off |\\n| 61%   80C    P2            137W /  140W |    2857MiB /  16376MiB |     90%      Default |\\n|                                         |                        |                  N/A |\\n+-----------------------------------------+------------------------+----------------------+\\n\\n+-----------------------------------------------------------------------------------------+\\n| Processes:                                                                              |\\n|  GPU   GI   CI              PID   Type   Process name                        GPU Memory |\\n|        ID   ID                                                               Usage      |\\n|=========================================================================================|\\n|    0   N/A  N/A            1546      C   ...space/fvdb-env/bin/python3.10       2850MiB |\\n+-----------------------------------------------------------------------------------------+\\n\")), mdx(\"p\", null, \"From this we can see this box now supports CUDA 13.0, keep this in mind.\"), mdx(\"p\", null, \"Now that we have the GPU drivers setup we will need to install all the python and fVDB dependencies, to simplify this\\nI have created a setup script that automates the process and makes customisation a bit easier:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"#!/usr/bin/env bash\\nset -euo pipefail\\n\\nPYTHON_VERSION=3.10\\nVENV_NAME=fvdb-env\\n\\nTORCH_VERSION=2.10.0\\nTORCH_CUDA=cu128\\nFVDB_CORE_VERSION=\\\"0.4.2+pt210.${TORCH_CUDA}\\\"\\n\\necho \\\"[0/5] Checking GPU...\\\"\\ncommand -v nvidia-smi >/dev/null || { echo \\\"nvidia-smi not found\\\"; exit 1; }\\nnvidia-smi >/dev/null || { echo \\\"GPU not working\\\"; exit 1; }\\n\\necho \\\"[1/5] System deps...\\\"\\nsudo apt update\\nsudo apt install -y \\\\\\n  python${PYTHON_VERSION} \\\\\\n  python${PYTHON_VERSION}-venv \\\\\\n  python3-pip \\\\\\n  build-essential \\\\\\n  git \\\\\\n  ninja-build \\\\\\n  cmake \\\\\\n  libgl1 \\\\\\n  libglib2.0-0\\n\\necho \\\"[2/5] Python env...\\\"\\npython${PYTHON_VERSION} -m venv $VENV_NAME\\nsource $VENV_NAME/bin/activate\\npip install --upgrade pip setuptools wheel\\n\\necho \\\"[3/5] PyTorch...\\\"\\npip install \\\\\\n  torch==${TORCH_VERSION} \\\\\\n  --index-url https://download.pytorch.org/whl/${TORCH_CUDA}\\n\\npython - <<EOF\\nimport torch\\nassert torch.cuda.is_available(), \\\"CUDA not available\\\"\\nprint(\\\"Torch:\\\", torch.__version__)\\nprint(\\\"GPU:\\\", torch.cuda.get_device_name(0))\\nEOF\\n\\necho \\\"[4/5] fVDB...\\\"\\npip install \\\\\\n  fvdb-core==${FVDB_CORE_VERSION} \\\\\\n  fvdb-reality-capture \\\\\\n  --extra-index-url https://d36m13axqqhiit.cloudfront.net/simple\\n\\necho \\\"[5/5] Verify...\\\"\\npython - <<EOF\\nimport torch, fvdb\\nassert torch.cuda.is_available()\\nx = torch.randn(1, device=\\\"cuda\\\")\\nprint(\\\"OK:\\\", x)\\nEOF\\n\\necho \\\"DONE \\u2192 source $VENV_NAME/bin/activate\\\"\\n\")), mdx(\"p\", null, \"By default, this script has CUDA 12.8 selected as to make this applicable to as many people as possible, however if\\nyour GPU supports CUDA 13 you can swap \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"TORCH_CUDA=cu128\"), \" to be \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"TORCH_CUDA=cu128\"), \".\"), mdx(\"p\", null, \"You should also update your \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"~/.bashrc\"), \" to include \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"export PATH=$PATH:$(pwd)/fvdb-env/bin\"), \" at the end of it so that\\non a new bash shell instance you have access to the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"frgs\"), \" cli tool.\"), mdx(\"p\", null, \"Given this blog post will be out of date the second a new version of fVDB is released i will also recommend that you check\\nout \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://openvdb.github.io/fvdb-core/installation.html\"\n  }, \"https://openvdb.github.io/fvdb-core/installation.html\"), \" and look at the Software requirements and adjust the torch and\\npython versions as required.\"), mdx(\"h2\", {\n    \"id\": \"getting-started-with-splatting-over-ssh\"\n  }, \"Getting started with splatting over SSH\"), mdx(\"p\", null, \"From this point onwards you can follow the tutorial over at \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://openvdb.github.io/fvdb-core/reality-capture/tutorials/frgs.html\"\n  }, \"https://openvdb.github.io/fvdb-core/reality-capture/tutorials/frgs.html\"), \"\\none little trick I can give is when you start using the commands like \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"frgs show\"), \" a web server will be hosted on port\\n8080 (or on any port you choose if you provide a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"-p 8888\"), \" argument). To view this site on your local machine\\nyou can open up a second SSH session which is mapping over that port via: \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"ssh -L 8080:127.0.0.1:8080 username@host\"), \"\\nwhere \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"username@host\"), \" is what you are using to connect to your ssh box. now you will be able to follow along fully\\nwith the tutorial!\"), mdx(\"p\", null, mdx(\"span\", {\n    parentName: \"p\",\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"650px\"\n    }\n  }, \"\\n      \", mdx(\"span\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"50.306748466257666%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABJ0AAASdAHeZh94AAACuklEQVQoz0WSy2tTeQCFf2mTJmle3t48bk2TmJKYtjZN29ub3CRN0tr0BVqs0qlhFIs6gzKOlWqlEKUKxVaNrRpfaDf1LcqsBmGYlYgrhVk4M6tZiSD4T3wSZXBx4KwOh/MdoaU0Ej0JIrEIsfYYPsWLLDv5cZfG8skxZg+kiYa9LP66nfkjQxzaq3F4r8ZINowa91NIhemNK0zv6KB8dDtCz+rkB/Nkchmy+SxetwMhBMdKKm9fHOW3a3sIKY08vlDk/GyOYd3HzEgzO3sd9LVaiW2xk+mVOflTkj0TcUQ2l6U4WiTdn0bPpmkNyrgsgiEtwMtbJZ6vjDBd8HB7IcPkUPhro6mxduyWOpp9DoItdnaNt7N7sJmoLBCpTIqatFQf3Wo3B6d1lmeTPFto5U2lg1crW/lj0c/T+QADCSchv51I0EZ9vcDjNpJP+ZmaiHP4h06O74h+C0z362h6knQ2yZuqxqdnKd7f6eZdNcFfN7t4X43x340Wrs5IxBQDXpegwSRobTHTEbHR1b4JXVUo9AcRmq5R27Ez0Ymq9fByKc7ftzv4557Kx0c6Hx4k+fOSylxpC+N5hUndQSljJaoYiASsbPY2ENpsItRsIuAzImp0g+Eg0bYoxbFRXt87wOcnGf5d19godzFR9CMHZQzyJoweiXqXhbaQiVFN5mDBzM6EIKLU45XqcEsGRG4gh5pU6enrYWBokIdXfub0zDa2tknUNTkRLgcm2U5DkxVhETQF3Ezun2Dp8hx3KyUelju5vs/MkVEnWqzh24a1u9Qo17zU4kU0WhEuO2aPA4vHgVFqxCTZGN89TOV6mfX7y1yqLrC0Os/K2gnWV6f4fbXAo9Oh75T/l83nxiQ7aFQkjLINg9OMsJm+Bp46+wt3Ny5SuVGmcvMMl6sLLK/NsbR2isWVY5ybH+MLKJtfv8GDteUAAAAASUVORK5CYII=')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"picture\", {\n    parentName: \"span\"\n  }, \"\\n          \", mdx(\"source\", {\n    parentName: \"picture\",\n    \"srcSet\": [\"/static/142462194b3ab979351c8cb14d789113/a81b5/splat-ssh-view.webp 163w\", \"/static/142462194b3ab979351c8cb14d789113/da3ef/splat-ssh-view.webp 325w\", \"/static/142462194b3ab979351c8cb14d789113/309d5/splat-ssh-view.webp 650w\", \"/static/142462194b3ab979351c8cb14d789113/78344/splat-ssh-view.webp 975w\", \"/static/142462194b3ab979351c8cb14d789113/bdb72/splat-ssh-view.webp 1300w\", \"/static/142462194b3ab979351c8cb14d789113/98cc8/splat-ssh-view.webp 1807w\"],\n    \"sizes\": \"(max-width: 650px) 100vw, 650px\",\n    \"type\": \"image/webp\"\n  }), \"\\n          \", mdx(\"source\", {\n    parentName: \"picture\",\n    \"srcSet\": [\"/static/142462194b3ab979351c8cb14d789113/5e043/splat-ssh-view.png 163w\", \"/static/142462194b3ab979351c8cb14d789113/e5cc6/splat-ssh-view.png 325w\", \"/static/142462194b3ab979351c8cb14d789113/663f3/splat-ssh-view.png 650w\", \"/static/142462194b3ab979351c8cb14d789113/d880f/splat-ssh-view.png 975w\", \"/static/142462194b3ab979351c8cb14d789113/4c573/splat-ssh-view.png 1300w\", \"/static/142462194b3ab979351c8cb14d789113/dc15e/splat-ssh-view.png 1807w\"],\n    \"sizes\": \"(max-width: 650px) 100vw, 650px\",\n    \"type\": \"image/png\"\n  }), \"\\n          \", mdx(\"img\", {\n    parentName: \"picture\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"src\": \"/static/142462194b3ab979351c8cb14d789113/663f3/splat-ssh-view.png\",\n    \"alt\": \"screenshot of the editor exposed by fCDB\",\n    \"title\": \"screenshot of the editor exposed by fCDB\",\n    \"loading\": \"lazy\",\n    \"decoding\": \"async\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    }\n  }), \"\\n        \"), \"\\n    \")));\n}\n;\nMDXContent.isMDXComponent = true;","slug":"/blog/2026/04/setup-fvdb-ubuntu-22-04/","tags":["ubuntu","gaussian-splat"],"caption":null,"videoSrcURL":null,"videoTitle":null,"githubEditPath":"https://github.com/falconmick/blog/edit/main/sites/blog/content/posts/2026-04-09-setup-fvdb-ubuntu-22.04/index.mdx","embeddedImagesLocal":null,"image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAADJElEQVQozwEZA+b8ADY8L0xWU2p2gpKhu6y+5ae53bG/4brE5L7I5sbP7cjO6sfM58bL6MzQ7M/R7MvQ7MfM6sLJ57vD5LfA4gB4fH58gYilsMq9yuy/yujO1/PU2vTb4Pjc3/XQ0N/X1ujHxNTIxNPU0+fY1+3c2/Da2vDR0+3HzOnDyOcAcXJjsLK94eD04eL2xcfcmJepo6Guq6izn5melYV7r6CbqZ6fp5qZwrS208nR39nn5eDx5N7v4d3u3trsAExQOFtgVKSjn7a1tHhye1dOUXZkVZV6ZI97bpeEeaKPhZ6LgI9/eZyJhKqamcG3v97W5ufg8Obf7+Td7gAyOio1PS9UUkxVTlJoWlSQeWqZhHSciXuYg3R/dnWlmJKciXp7bWaFdnKHdW2bi4W5s7nKyNLRztza1ucAICYcQ0NCW1JcWE1QcGBbcWJbYldWc2hhgW9ij4F5iX97g3NsiXlzf3Fsf3Foint2k4eDkYt9kY+DkZGKACYsIGVWSmJPQXtnWFFBK0k0E1pFJG1dT045IW9aRX1uYnFdS4lxWZyEcn9xaYB0bol+eHdvYF1dRT5DMQAuNhZqWENTLyGMbmF5Y05aRSpwVjyXf3A9JA5fSTSPfG56ZU+Eb1ybhniHem1ya19yaldtZ1FOSzUuMh8APT80bF1UaU5AVVEqWk0sZVsrZU4zbFhPZ1JPc11QgnJbem1RdGhTZ19IbGNPcGZZdm5kenRtdnFrcnBrAH9uZ3dwYWBiQlFNKV5SLG1rP3JxR356T5OKXYWAS4SATn93UnNqSGxjRXFlU39yZIR4cpSJiqKZoJmToQA0Mhg0NB9lXktyYVhMPS5ZWzp2eEB9gDx4fDd7fjl/gD5+e0N8dk2AeFmFe2CEeWmSiIaSiI2Rh46IfogANjYkbl9dSD9DPTs7Sk83UVkuV2AzWmIvV14rV14uXWM0Y2M6bGhEamVIa2RRa2Jcc2prdm90enJ6cWp1ADMzJTw6LyQoGjU8ITtEJD9JJT9KJUFLKERNJ0hQJ09TLlNUN1VUOVZUPWFbU19YWVtWXGBaYWNcZmBZZGCqefEASDO0AAAAAElFTkSuQmCC"},"images":{"fallback":{"src":"/static/683eecc4bc035db938c9d32f78d88370/7f832/house-splat.png","srcSet":"/static/683eecc4bc035db938c9d32f78d88370/47ec8/house-splat.png 750w,\n/static/683eecc4bc035db938c9d32f78d88370/e0d77/house-splat.png 1080w,\n/static/683eecc4bc035db938c9d32f78d88370/523a5/house-splat.png 1366w,\n/static/683eecc4bc035db938c9d32f78d88370/7f832/house-splat.png 1536w","sizes":"100vw"},"sources":[{"srcSet":"/static/683eecc4bc035db938c9d32f78d88370/3c4c5/house-splat.webp 750w,\n/static/683eecc4bc035db938c9d32f78d88370/54559/house-splat.webp 1080w,\n/static/683eecc4bc035db938c9d32f78d88370/cc717/house-splat.webp 1366w,\n/static/683eecc4bc035db938c9d32f78d88370/67f98/house-splat.webp 1536w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6666666666666666}},"extension":"png","publicURL":"/static/683eecc4bc035db938c9d32f78d88370/house-splat.png"},"socialImage":{"extension":"png","publicURL":"/static/683eecc4bc035db938c9d32f78d88370/house-splat.png"}}},"pageContext":{"id":"25543cf5-bbb7-5c2c-82b5-295f54a1f558"}},
    "staticQueryHashes": ["1849085223","4250269005"]}