Skip to content

[MLA-1981] Don't allow connections to newer python trainers #5370

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Project/Packages/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
"com.unity.analytics": "3.2.3",
"com.unity.collab-proxy": "1.2.15",
"com.unity.ml-agents": "file:../../com.unity.ml-agents",
"com.unity.package-manager-ui": "2.0.8",
"com.unity.package-manager-ui": "2.0.13",
"com.unity.package-validation-suite": "0.7.15-preview",
"com.unity.purchasing": "2.0.3",
"com.unity.purchasing": "2.2.1",
"com.unity.textmeshpro": "1.4.1",
"com.unity.modules.ai": "1.0.0",
"com.unity.modules.animation": "1.0.0",
Expand Down
2 changes: 1 addition & 1 deletion Project/ProjectSettings/ProjectVersion.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
m_EditorVersion: 2018.4.17f1
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This (and the manifest) were pretty old. Just affects Project, but it's annoying to keep excluding them.

m_EditorVersion: 2018.4.32f1
3 changes: 2 additions & 1 deletion com.unity.ml-agents/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ and this project adheres to
### Bug Fixes
#### com.unity.ml-agents (C#)
- Fixed a null reference exception that occurred when loading an ONNX model file that was generated with a new
version of the Python trainer (0.26.0 or newer).
version of the Python trainer (0.26.0 or newer). (#5350)
- Added checked to prevent training with incompatible versions of the python trainer (0.26.0 or newer). (#5370)

## [1.0.7] - 2021-03-04
### Minor Changes
Expand Down
2 changes: 1 addition & 1 deletion com.unity.ml-agents/Documentation~/com.unity.ml-agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Manager documentation].
To install the companion Python package to enable training behaviors, follow the
[installation instructions] on our [GitHub repository]. It is strongly recommended that you
use the Python package that corresponds to this release (version 0.16.1) for the best experience;
versions between 0.16.1 and 0.20.0 are supported.
versions between 0.16.1 and 0.20.0 are supported. Versions after 0.25.1 cannot be used.

## Requirements

Expand Down
54 changes: 52 additions & 2 deletions com.unity.ml-agents/Runtime/Communicator/RpcCommunicator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEngine;
using Unity.MLAgents.Analytics;
using Unity.MLAgents.CommunicatorObjects;
Expand Down Expand Up @@ -99,6 +100,41 @@ internal static bool CheckCommunicationVersionsAreCompatible(
}

internal static bool CheckPythonPackageVersionIsCompatible(string pythonLibraryVersion)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The diff is messy; the old code was renamed to CheckPythonPackageVersionIsSupported.

{
// Try to extract the numerical values from the pythonLibraryVersion, e.g. remove the ".dev0" suffix
var versionMatch = Regex.Match(pythonLibraryVersion, @"[0-9]+\.[0-9]+\.[0-9]");
if (versionMatch.Success)
{
pythonLibraryVersion = versionMatch.Value;
}

Version pythonVersion;
try
{
pythonVersion = new Version(pythonLibraryVersion);
}
catch
{
// Unparseable version.
// Anything like 0.42.0.dev0 should have been caught with the regex above, so anything here
// is totally bogus. For now, ignore these and let CheckPythonPackageVersionIsSupported handle it.
return true;
}

if (pythonVersion > PythonTrainerVersions.s_MaxCompatibleVersion)
{
return false;
}
return true;
}

/// <summary>
/// Check if the package is in the supported range. Note that some versions might be unsupported but
/// still compatible.
/// </summary>
/// <param name="pythonLibraryVersion"></param>
/// <returns></returns>
internal static bool CheckPythonPackageVersionIsSupported(string pythonLibraryVersion)
{
Version pythonVersion;
try
Expand All @@ -107,7 +143,7 @@ internal static bool CheckPythonPackageVersionIsCompatible(string pythonLibraryV
}
catch
{
// Unparseable - this also catches things like "0.20.0-dev0" which we don't want to support
// Unparseable - this also catches things like "0.20.0.dev0" which we don't want to support
return false;
}

Expand Down Expand Up @@ -182,7 +218,21 @@ public UnityRLInitParameters Initialize(CommunicatorInitParameters initParameter
throw new UnityAgentsException("ICommunicator.Initialize() failed.");
}

var packageVersionSupported = CheckPythonPackageVersionIsCompatible(pythonPackageVersion);
var packageVersionCompatible = CheckPythonPackageVersionIsCompatible(pythonPackageVersion);
if (!packageVersionCompatible)
{
Debug.LogErrorFormat(
"Python package version ({0}) will produce model files that are incompatible with this " +
"version of the com.unity.ml-agents Unity package. Please downgrade to a Python package " +
"between {1} and {2}, or update to a new version of com.unity.ml-agents.",
pythonPackageVersion,
PythonTrainerVersions.s_MinSupportedVersion,
PythonTrainerVersions.s_MaxSupportedVersion
);
throw new UnityAgentsException("Incompatible trainer version.");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This gets caught and a different exception is thrown below.

}

var packageVersionSupported = CheckPythonPackageVersionIsSupported(pythonPackageVersion);
if (!packageVersionSupported)
{
Debug.LogWarningFormat(
Expand Down
6 changes: 5 additions & 1 deletion com.unity.ml-agents/Runtime/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ internal enum MenuGroup

internal static class PythonTrainerVersions
{
// The python package version must be >= s_MinSupportedVersion
// The python package version should be >= s_MinSupportedVersion
// and <= s_MaxSupportedVersion.
internal static Version s_MinSupportedVersion = new Version("0.16.1");
internal static Version s_MaxSupportedVersion = new Version("0.20.0");

// Any version > to this is known to be incompatible and we will block training.
// Covers any patch to the release before the 2.0.0 package release.
internal static Version s_MaxCompatibleVersion = new Version("0.25.999");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just in case we do a 0.25.2 patch release.

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,39 @@ public void TestCheckCommunicationVersionsAreCompatible()
[Test]
public void TestCheckPythonPackageVersionIsCompatible()
{
Assert.IsFalse(RpcCommunicator.CheckPythonPackageVersionIsCompatible("0.13.37")); // too low
Assert.IsFalse(RpcCommunicator.CheckPythonPackageVersionIsCompatible("0.42.0")); // too high
Assert.IsTrue(RpcCommunicator.CheckPythonPackageVersionIsCompatible("0.13.37")); // low is OK
Assert.IsFalse(RpcCommunicator.CheckPythonPackageVersionIsCompatible("0.26.0")); // too high

// These are fine
Assert.IsTrue(RpcCommunicator.CheckPythonPackageVersionIsCompatible("0.16.1"));
Assert.IsTrue(RpcCommunicator.CheckPythonPackageVersionIsCompatible("0.17.17"));
Assert.IsTrue(RpcCommunicator.CheckPythonPackageVersionIsCompatible("0.20.0"));
Assert.IsTrue(RpcCommunicator.CheckPythonPackageVersionIsCompatible("0.25.0"));
Assert.IsTrue(RpcCommunicator.CheckPythonPackageVersionIsCompatible("0.25.1"));
Assert.IsTrue(RpcCommunicator.CheckPythonPackageVersionIsCompatible("0.25.2"));

// "dev" strings should get removed before parsing
Assert.IsTrue(RpcCommunicator.CheckPythonPackageVersionIsCompatible("0.17.0.dev0"));
Assert.IsTrue(RpcCommunicator.CheckPythonPackageVersionIsCompatible("0.25.0.dev0"));
Assert.IsFalse(RpcCommunicator.CheckPythonPackageVersionIsCompatible("0.26.0.dev0"));

// otherwise unparseable - keep support for these
Assert.IsTrue(RpcCommunicator.CheckPythonPackageVersionIsCompatible("the airspeed velocity of an unladen swallow"));
}

[Test]
public void TestCheckPythonPackageVersionIsSupported()
{
Assert.IsFalse(RpcCommunicator.CheckPythonPackageVersionIsSupported("0.13.37")); // too low
Assert.IsFalse(RpcCommunicator.CheckPythonPackageVersionIsSupported("0.42.0")); // too high

// These are fine
Assert.IsTrue(RpcCommunicator.CheckPythonPackageVersionIsSupported("0.16.1"));
Assert.IsTrue(RpcCommunicator.CheckPythonPackageVersionIsSupported("0.17.17"));
Assert.IsTrue(RpcCommunicator.CheckPythonPackageVersionIsSupported("0.20.0"));

// "dev" string or otherwise unparseable
Assert.IsFalse(RpcCommunicator.CheckPythonPackageVersionIsCompatible("0.17.0-dev0"));
Assert.IsFalse(RpcCommunicator.CheckPythonPackageVersionIsCompatible("oh point seventeen point oh"));
Assert.IsFalse(RpcCommunicator.CheckPythonPackageVersionIsSupported("0.17.0.dev0"));
Assert.IsFalse(RpcCommunicator.CheckPythonPackageVersionIsSupported("oh point seventeen point oh"));
}
}
}