Open-source project
Linketic/CityGaussian avatar
Linketic/CityGaussian

CityGaussian ships as a Gaussian Lightning fork with two branches and two lineages of code

[ECCV`24&ICLR`25] CityGaussian Series for High-quality Large-Scale Scene Reconstruction with Gaussians

1,266 stars111 forksJupyter NotebookNOASSERTION

At a glance

What is it?
CityGaussian is the research tree behind a pair of large scale scene reconstruction papers, and main now sits on top of Gaussian Lightning v0.10.1. Installing it gives you the upstream package name and console scripts, the V1 code lives on a second branch, and the newest release is eight months older than the last push.
Who is it for?
CityGaussian is worth reading for anyone building city scale Gaussian splatting, but it is a research tree rather than a library.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 50 days ago.
What is it written in?
Mainly Jupyter Notebook, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 4, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The package installs as gaussian-splatting-lightning, not CityGaussian

Installing from this tree hands you the name of the project main was rebased onto. The `[project]` block in pyproject.toml calls it `gaussian-splatting-lightning`, declares the version as dynamic instead of writing a number anywhere, and asks for Python 3.8 or newer. The console scripts it registers are `gs-fit`, `gs-val`, `gs-test` and `gs-predict`, followed by four `segany-*` twins and a `gs-viewer` entry. Not one of them carries the word CityGaussian, so the command you type after installing this repository is the same command you would type after installing Gaussian Lightning itself.

That mismatch is what a scripted user hits first. A CI job or a Makefile expecting a citygs command finds nothing, because the fit entry point is `internal.entrypoints.gspl:cli_fit` and the segany group resolves to `internal.entrypoints.seganygs`. The Getting Started section does not print either name: it links four separate doc files, and none of those four links is a command you can paste.

main was rebased onto Gaussian Lightning, so V1 lives on another branch

The paragraph under the paper links says the main branch has been rebased to Gaussian Lightning v0.10.1 and sends anyone who needs the original V1 code to a branch named `V1-Original`. One repository therefore holds two incompatible layouts: the code behind the ECCV paper on one branch, the current code on another, with no tag that says which is which. The release names point at the same split from the other direction, `CityGaussian_V2.0`, `CityGaussian_V1.5` and `CityGaussian_V1.2`, none of which lines up with the 7.x version scheme the project it now sits on uses.

The News list ends at 2025.10.18, the entry announcing support and guidance for joint pose and 3DGS optimization with VGGT-X, and the newest release is CityGaussian_V2.0 from 2025-01-22. The branch itself was pushed on 2026-08-16. That gap is the practical question for anyone pinning a commit, because the code that exists on main is newer than anything the releases point at, and the release list gives no way to tell which main commit a given tag was cut from.

The license carries a NonCommercial clause the repository field does not show

The license section of the README links Creative Commons Attribution-NonCommercial-ShareAlike 4.0, and the tree carries a file called `LICENSE.md`. The license field on the repository page reads NOASSERTION, so the metadata tells a visitor nothing, and a reader has to open either the README or a file whose extension is not the usual bare `LICENSE` to learn the terms.

For research use that difference costs nothing. For anyone doing city scale reconstruction as part of commercial work, the NonCommercial term is the whole question, and it is not in the file name. The repository description carries venue tags written as `[ECCV`24&ICLR`25]`, with backticks inside the bracket, which is a paste artifact from the paper title rather than a structured field.

The ShareAlike half reaches the checkpoints as well. The CityGaussian V2 weights are offered from a Baidu Netdisk folder with the password carried inside the link and from a Hugging Face repository, so the same weights sit on two different networks, and anyone passing them along inherits the same conditions.

setuptools packages internal and utils, and the root scripts stay behind

The include list in pyproject.toml is narrow:

toml
[tool.setuptools.packages.find]
include = ["internal*", "utils*"]

The tree puts five Python files at the root: `main.py`, `render.py`, `dataset.py`, `seganygs.py` and `viewer.py`. None of them sits inside `internal/` or `utils/`, so an install built from this manifest packages the library directories and leaves the entry scripts behind. That fits how the project is meant to be used, from a checkout, but it means the install step in `doc/installation.md` is closer to building an environment than to putting a working command on your PATH.

The dependency list is one line long. `requirements.txt` contains nothing but a single include, `-r requirements/lightning23.txt`, which points into the `requirements/` directory for the actual packages, and the file name pins the Lightning series the code was written against. The move onto Gaussian Lightning v0.10.1 is therefore visible in that pinned include as well as in the README paragraph.

COLMAP poses come from the dataset, not from a fresh match

The README's own FAQ entry on generating COLMAP results explains the shortcut the pipeline takes: the ground truth poses offered by the datasets are used, and the train and test sets are matched separately. That is described as faster than matching from scratch, with the concession that it still costs a lot of time. A reproduction therefore does not begin with raw images. It begins with a pose file the dataset already provides, which means the dataset has to ship one, and it means the pose error a from scratch match would have introduced never reaches the results table at all.

The second FAQ entry covers the failure that arrives first for most people. Out of memory during training is answered with three levers: downsample the images, lower `max_cache_num` in `train_large.py`, which the authors say they ran at a rather large 1024, or raise `prune_ratio` in parallel tuning. The third entry covers blocks that never train. When the data assigned to a block is fewer than 50, the block is left untrained on purpose to prevent overfitting, and the cause is put on an unreasonable aabb setting.

Street level F1 scores trade precision for recall, and depth_ratio is the knob

The results table lines up five scenes, LFLS, SMBU, Upper Campus, MatrixCity Aerial and MatrixCity Street, with SSIM and PSNR for the images, LPIPS, precision, recall and F1 for the mesh, and a Gaussian count in millions. The street row is the outlier: MatrixCity Street scores 0.325 precision against 0.797 recall, an F1 of 0.461, and 7.40 million Gaussians. The note under the table says that F1 sits below the value reported in the paper because precision is sacrificed for better recall and a more complete road surface.

The knob for that trade sits one sentence later. Setting `depth_ratio` to 0.0 leaves the road unbroken, and the note says surface reconstruction performance will be worse in exchange. Read carelessly, the F1 column looks like a quality ranking of the five scenes, when what it records is a configuration choice about how much road you want versus how clean the geometry is. Both ends of that dial cost something.

doc/run&eval.md needs quoting in any shell

Four links make up the Getting Started section, and one of them is named `doc/run&eval.md`. An ampersand inside a path is a shell metacharacter, so `cd doc/run&eval.md` backgrounds a job and `less doc/run&eval.md` pipes the output of a command that does not exist into a pager. Quoting the path makes it behave. The other three files, `doc/installation.md`, `doc/data_preparation.md` and `doc/render_video.md`, have no such problem.

The layout around those files explains the rest of the shape. `configs/`, `scripts/` and `tools/` sit beside `blender/`, `tests/` and `notebooks/`, and the repository is indexed under Jupyter Notebook as its primary language even though every entry point in the manifest is a Python module. A `.gitmodules` file and a `submodules/` directory are both present at the top level, so a fresh clone brings external dependencies whose contents do not live in this tree, and doc/installation.md is where that step is expected to be handled.

Editorial conclusion

CityGaussian is worth reading for anyone building city scale Gaussian splatting, but it is a research tree rather than a library. Pick the branch before you pick anything else, because main and V1-Original do not share a layout; expect to set up an environment from a checkout with submodules and a pinned Lightning include rather than to install a package from a registry; and read LICENSE.md before any use with a company behind it, since the NonCommercial term is easy to miss while the license field on the repository page reads NOASSERTION. Anyone who needs a release to pin against should note that the newest tag is CityGaussian_V2.0 from 2025-01-22 while the branch was pushed on 2026-08-16.

Frequently asked questions

What license does CityGaussian use?

The README links Creative Commons Attribution-NonCommercial-ShareAlike 4.0 and the tree carries LICENSE.md, while the license field on the repository page reads NOASSERTION. The NonCommercial term is the part to read before any commercial use.

Is the CityGaussian V1 code still on the main branch?

No. Main has been rebased to Gaussian Lightning v0.10.1, and the original V1 code was moved to a branch called V1-Original. The README states this in the paragraph directly under the paper links.

Where are the CityGaussian V2 checkpoints hosted?

Two places: a Baidu Netdisk folder whose link carries the extraction code, and the TeslaYang123/CityGaussianV2 repository on Hugging Face. The ShareAlike half of the license travels with the weights.

Why does CityGaussian skip training on some blocks?

A block assigned fewer than 50 data items is left untrained on purpose, to prevent overfitting. The README attributes the pattern to an unreasonable aabb setting and suggests adjusting it.

How do you install CityGaussian from the repository?

doc/installation.md is the only written path; the Getting Started section links four doc files rather than printing a command. requirements.txt holds a single include, requirements/lightning23.txt, and the manifest asks for Python 3.8 or newer.

Can CityGaussian be used for commercial work?

The terms named in the README are Attribution-NonCommercial-ShareAlike 4.0, which bar commercial use. Because the license field on the repository page reads NOASSERTION, LICENSE.md is the file that settles the question.

Official sources

  1. Issues
  2. Linketic/CityGaussian on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/linketic-citygaussian.svg)](https://hysenlabs.com/projects/linketic-citygaussian)