ludwig-ai--ludwig
593b94c120
pytest / Unit Tests (push) Has been cancelled
pytest / Integration (integration_tests_a) (push) Has been cancelled
pytest / Integration (integration_tests_b) (push) Has been cancelled
pytest / Integration (integration_tests_c) (push) Has been cancelled
pytest / Integration (integration_tests_d) (push) Has been cancelled
pytest / Integration (integration_tests_e) (push) Has been cancelled
pytest / Integration (integration_tests_f) (push) Has been cancelled
pytest / Integration (integration_tests_g) (push) Has been cancelled
pytest / Integration (integration_tests_h) (push) Has been cancelled
pytest / Integration (integration_tests_i) (push) Has been cancelled
pytest / Integration (integration_tests_j) (push) Has been cancelled
pytest / Distributed (distributed_a) (push) Has been cancelled
pytest / Distributed (distributed_b) (push) Has been cancelled
pytest / Distributed (distributed_c) (push) Has been cancelled
pytest / Distributed (distributed_d) (push) Has been cancelled
pytest / Distributed (distributed_e) (push) Has been cancelled
pytest / Distributed (distributed_f) (push) Has been cancelled
pytest / Minimal Install (push) Has been cancelled
pytest / Event File (push) Has been cancelled
pytest (slow) / py-slow (push) Has been cancelled
Publish JSON Schema / publish-schema (push) Has been cancelled
113 行
4.1 KiB
Python
113 行
4.1 KiB
Python
# Copyright (c) 2023 Predibase, Inc., 2020 Uber Technologies, Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
# ==============================================================================
|
|
import os
|
|
import shutil
|
|
|
|
import numpy as np
|
|
import torch
|
|
|
|
from ludwig.api import LudwigModel
|
|
from ludwig.collect import collect_activations, collect_weights, print_model_summary
|
|
from ludwig.constants import BATCH_SIZE, ENCODER, TRAINER, TYPE
|
|
from ludwig.globals import MODEL_FILE_NAME
|
|
from ludwig.utils.torch_utils import get_torch_device
|
|
from tests.integration_tests.utils import category_feature, ENCODERS, generate_data, sequence_feature
|
|
|
|
DEVICE = get_torch_device()
|
|
|
|
|
|
def _prepare_data(csv_filename):
|
|
# Single sequence input, single category output
|
|
input_features = [sequence_feature(encoder={"reduce_output": "sum"})]
|
|
output_features = [category_feature(decoder={"vocab_size": 2}, reduce_input="sum")]
|
|
|
|
input_features[0][ENCODER][TYPE] = ENCODERS[0]
|
|
|
|
# Generate test data
|
|
data_csv = generate_data(input_features, output_features, csv_filename)
|
|
return input_features, output_features, data_csv
|
|
|
|
|
|
def _train(input_features, output_features, data_csv, **kwargs):
|
|
config = {
|
|
"input_features": input_features,
|
|
"output_features": output_features,
|
|
"combiner": {"type": "concat", "output_size": 14},
|
|
TRAINER: {"epochs": 2, BATCH_SIZE: 128},
|
|
}
|
|
|
|
model = LudwigModel(config)
|
|
_, _, output_dir = model.train(dataset=data_csv, **kwargs)
|
|
return model, output_dir
|
|
|
|
|
|
def _get_layers(model_path):
|
|
model = LudwigModel.load(model_path)
|
|
return [name for name, _ in model.model.named_children()]
|
|
|
|
|
|
def _collect_activations(model_path, layers, csv_filename, output_directory):
|
|
return collect_activations(model_path, layers, dataset=csv_filename, output_directory=output_directory)
|
|
|
|
|
|
def test_collect_weights(tmpdir, csv_filename):
|
|
output_dir = None
|
|
try:
|
|
model, output_dir = _train(*_prepare_data(csv_filename))
|
|
model_path = os.path.join(output_dir, MODEL_FILE_NAME)
|
|
|
|
# 1 for the encoder (embeddings).
|
|
# 2 for the decoder classifier (w and b).
|
|
weights = [w for _, w in model.model.collect_weights()]
|
|
assert len(weights) == 3
|
|
|
|
# Load model from disk to ensure correct weight names
|
|
model_loaded = LudwigModel.load(model_path)
|
|
tensor_names = [name for name, w in model_loaded.collect_weights()]
|
|
assert len(tensor_names) == 3
|
|
|
|
filenames = collect_weights(model_path, tensor_names, tmpdir)
|
|
assert len(filenames) == 3
|
|
|
|
for weight, filename in zip(weights, filenames):
|
|
saved_weight = np.load(filename)
|
|
assert torch.allclose(weight, torch.from_numpy(saved_weight).to(DEVICE), rtol=1.0e-4), filename
|
|
finally:
|
|
if output_dir:
|
|
shutil.rmtree(output_dir, ignore_errors=True)
|
|
|
|
|
|
def test_collect_activations(tmpdir, csv_filename):
|
|
output_dir = None
|
|
try:
|
|
model, output_dir = _train(*_prepare_data(csv_filename))
|
|
model_path = os.path.join(output_dir, MODEL_FILE_NAME)
|
|
|
|
# [last_hidden, logits, projection_input]
|
|
filenames = _collect_activations(
|
|
model_path, [name for name, _ in model.model.named_children()], csv_filename, tmpdir
|
|
)
|
|
assert len(filenames) == 3
|
|
finally:
|
|
if output_dir:
|
|
shutil.rmtree(output_dir, ignore_errors=True)
|
|
|
|
|
|
def test_print_model_summary(csv_filename):
|
|
output_dir = None
|
|
model, output_dir = _train(*_prepare_data(csv_filename))
|
|
model_path = os.path.join(output_dir, MODEL_FILE_NAME)
|
|
print_model_summary(model_path)
|