**Use case**

Generate models once and reuse them.

**Describe the solution you'd like**

Add command line options:
```
--save file - write serialized models on disk after training and before generating the data; the user can set --limit to 0 to only train the models and save them without proceeding to data generation;
--load file - instead of training the models, load the prepared models from the file and start generating the data.
```

Serialization format: one byte for version (equals to 0), then simple binary serialization of all the models; the whole file is compressed with ZSTD level 1 using CompressedWriteBuffer (no need to allow any compression options to choose).
{
private:
    ModelPtr nested_model;
public:
    explicit ArrayModel(ModelPtr nested_model_) : nested_model(std::move(nested_model_)) {}
    void train(const IColumn & column) override
    {
        const ColumnArray & column_array = assert_cast<const ColumnArray &>(column);
        const IColumn & nested_column = column_array.getData();
        nested_model->train(nested_column);
    }
    void finalize() override
    {
        nested_model->finalize();
    }
    ColumnPtr generate(const IColumn & column) override
    {
        const ColumnArray & column_array = assert_cast<const ColumnArray &>(column);
        const IColumn & nested_column = column_array.getData();
        ColumnPtr new_nested_column = nested_model->generate(nested_column);
        return ColumnArray::create(IColumn::mutate(std::move(new_nested_column)), IColumn::mutate(column_array.getOffsetsPtr()));
    }
    void updateSeed() override
    {
        nested_model->updateSeed();
    }
};
class NullableModel : public IModel