IGNF / myria3d

Myria3D: Aerial Lidar HD Semantic Segmentation with Deep Learning
https://ignf.github.io/myria3d/
BSD 3-Clause "New" or "Revised" License
169 stars 23 forks source link

Myria3D on Windows Server #51

Closed JuilsonJubanski closed 1 year ago

JuilsonJubanski commented 1 year ago

Hi!

Firstly I want to say that your work is really amazing! This will help us to produce muche better maps! Nevertheless I am trying to put Myria3D to run on Windows Server 2019, with a powerfull GPU (NVIDEA RTX A5000). I was able to install and activate the environment, but when I try to run any prediction I got always the same:

python -m myria3d.predict --config-path "C:\Anaconda\myria3d\configs\hydra" --config-name "proto151_V2.0_epoch_100_Myria3DV3.1.0_predict_config_V3.2.0" predict.src_las=C:\Anaconda\myria3d\PTS_LAMB93_IGN69_0877_6603.las predict.output_dir=C:/Anaconda/myria3d/tests/class predict.ckpt_path=C:/Anaconda/myria3d/model/proto151_V2.0_epoch_100_Myria3DV3.1.0.ckpt predict.gpus=0 datamodule.batch_size=50 hydra.run.dir=C:/Anaconda/myria3d/configs/hydra/log

0it [00:00, ?it/s] | 0/1 [00:00<?, ?it/s] 0%| | 0/1 [00:01<?, ?it/s] Error executing job with overrides: ['predict.src_las=C:\Anaconda\myria3d\PTS_LAMB93_IGN69_0877_6603.las', 'predict.output_dir=C:/Anaconda/myria3d/tests/class', 'predict.ckpt_path=C:/Anaconda/myria3d/model/proto151_V2.0_epoch_100_Myria3DV3.1.0.ckpt', 'predict.gpus=0', 'datamodule.batch_size=50'] Traceback (most recent call last): File "C:\ProgramData\Anaconda3\envs\myria3d\lib\runpy.py", line 197, in _run_module_as_main return _run_code(code, main_globals, None, File "C:\ProgramData\Anaconda3\envs\myria3d\lib\runpy.py", line 87, in _run_code exec(code, run_globals) File "C:\Anaconda\myria3d\myria3d\predict.py", line 104, in main() File "C:\Anaconda\myria3d\myria3d\utils\utils.py", line 159, in timed result = method(*args, *kwargs) File "C:\ProgramData\Anaconda3\envs\myria3d\lib\site-packages\hydra\main.py", line 48, in decorated_main _run_hydra( File "C:\ProgramData\Anaconda3\envs\myria3d\lib\site-packages\hydra_internal\utils.py", line 377, in _run_hydra run_and_report( File "C:\ProgramData\Anaconda3\envs\myria3d\lib\site-packages\hydra_internal\utils.py", line 214, in run_and_report raise ex File "C:\ProgramData\Anaconda3\envs\myria3d\lib\site-packages\hydra_internal\utils.py", line 211, in run_andreport return func() File "C:\ProgramData\Anaconda3\envs\myria3d\lib\site-packages\hydra_internal\utils.py", line 378, in lambda: hydra.run( File "C:\ProgramData\Anaconda3\envs\myria3d\lib\site-packages\hydra_internal\hydra.py", line 111, in run = ret.return_value File "C:\ProgramData\Anaconda3\envs\myria3d\lib\site-packages\hydra\core\utils.py", line 233, in return_value raise self._return_value File "C:\ProgramData\Anaconda3\envs\myria3d\lib\site-packages\hydra\core\utils.py", line 160, in run_job ret.return_value = task_function(task_cfg) File "C:\Anaconda\myria3d\myria3d\predict.py", line 100, in main predict(config) File "C:\Anaconda\myria3d\myria3d\utils\utils.py", line 159, in timed result = method(args, **kwargs) File "C:\Anaconda\myria3d\myria3d\predict.py", line 57, in predict for batch in tqdm(datamodule.predict_dataloader()): File "C:\ProgramData\Anaconda3\envs\myria3d\lib\site-packages\tqdm\std.py", line 1195, in iter for obj in iterable: File "C:\ProgramData\Anaconda3\envs\myria3d\lib\site-packages\torch\utils\data\dataloader.py", line 368, in iter return self._get_iterator() File "C:\ProgramData\Anaconda3\envs\myria3d\lib\site-packages\torch\utils\data\dataloader.py", line 314, in _get_iterator return _MultiProcessingDataLoaderIter(self) File "C:\ProgramData\Anaconda3\envs\myria3d\lib\site-packages\torch\utils\data\dataloader.py", line 927, in init w.start() File "C:\ProgramData\Anaconda3\envs\myria3d\lib\multiprocessing\process.py", line 121, in start self._popen = self._Popen(self) File "C:\ProgramData\Anaconda3\envs\myria3d\lib\multiprocessing\context.py", line 224, in _Popen return _default_context.get_context().Process._Popen(process_obj) File "C:\ProgramData\Anaconda3\envs\myria3d\lib\multiprocessing\context.py", line 327, in _Popen return Popen(process_obj) File "C:\ProgramData\Anaconda3\envs\myria3d\lib\multiprocessing\popen_spawn_win32.py", line 93, in init reduction.dump(process_obj, to_child) File "C:\ProgramData\Anaconda3\envs\myria3d\lib\multiprocessing\reduction.py", line 60, in dump ForkingPickler(file, protocol).dump(obj) AttributeError: Can't pickle local object 'TargetTransform._set_preprocessing_mapper..' (myria3d) PS C:\Anaconda\myria3d> Traceback (most recent call last): File "", line 1, in File "C:\ProgramData\Anaconda3\envs\myria3d\lib\multiprocessing\spawn.py", line 116, in spawn_main exitcode = _main(fd, parent_sentinel) File "C:\ProgramData\Anaconda3\envs\myria3d\lib\multiprocessing\spawn.py", line 126, in _main self = reduction.pickle.load(from_parent) EOFError: Ran out of input

I don't know if I'm doing something very wrong, or Windows is not able to run this. Could you please help me?

lobnico commented 1 year ago

I do run it on windows but within a Ubuntu environnement. Docker could be used as well

CharlesGaydon commented 1 year ago

Hi @JuilsonJubanski, and apologies for the (holiday-related) delay ! Happy that this project could be of any help 😀

It does seem that on Windows python has a hard time with serializing method TargetTransform._set_preprocessing_mapper, which may be due to a form of closure : the function np.vectorize returns a Callable (then set to self.preprocessing_mapper). it seems that serializing functions with a closure (or a lambda) is performed by an extension of pickle : dill. The error happens when multiprocessing is required by the torch dataloader. Since it works within Ubuntu, I assume that it is fixed in torch. Are you using the version specified in the environment.yml file?

If this is the case, I can think of a possible workaround that may work : getting rid of _set_preprocessing_mapper and _set_mapper methods in class [TargetTransform](https://github.com/IGNF/myria3d/blob/9587e80c8d5df7a7792dad7fb71c64300f158397/myria3d/pctl/transforms/transforms.py#L166) so that closure happens in init. I think that this might make it pickable. I cannot test this on Windows but if you are confortable with small modifications of the code this might be a quick fix. :)


Alternatively, running via a Docker container (even in Windows) might be a straightforward workaround. I'd be happy to provide a docker image if you need one.

CharlesGaydon commented 1 year ago

@lobnico Thanks for sharing. I am eager for any feedback on your use case and your experience with the package. Feel free to reach out :)

lobnico commented 1 year ago

Maybe discussion tab could be enabled in order to reach out / share insights.

Very good experience so far! Inference is about 2.5min / 1km² on a RTX3080.

No color / IR in ign lidar data, so we switched model's input with intensity instead.

With config checkpoint v3.2; eyeballing 75-90% correct ground /building / vegetation segmentation, with a plus for vegetation. This was pretty consistent as far as tested across a big city and some remote areas. It is already implemented as a tool to mass produce ground heightmaps / meshes, but it can obviously do a lot more.

CharlesGaydon commented 1 year ago

Great idea, I'll open discussions soon! This will help gather new ideas and needs from the community, as well as feedback on ease of use. :)

I am very happy to hear that this our model and code are contributing to your work! The performance you describe are coherent with the ones we document in a Model Card stored (see Production Assets - in French): image

Closing this issue since a nice PR is incoming to help Windows user get started with Myria3D.

CharlesGaydon commented 1 year ago

No color / IR in ign lidar data, so we switched model's input with intensity instead.

@lobnico Just wanted to mention that Lidar can be colorized with IGN Orthoimages data, with tools like PDAL.